首先阅读一下man手册
对于IPV4地址
IPv4 network address in dotted-decimal format, "ddd.ddd.ddd.ddd", where ddd is a decimal
number of up to three digits in the range 0 to 255. The address is converted to a struct in_addr and copied to dst, which must be sizeof(struct in_addr) (4) bytes (32 bits) long.
/* Internet address. */
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
对于IPv6地址
src points to a character string containing an IPv6 network address. The address is converted to a struct in6_addr and copied to dst, which must be sizeof(struct in6_addr) (16) bytes (128 bits) long.
#ifndef __USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr
{
union
{
uint8_t __u6_addr8[16];
#if defined __USE_MISC || defined __USE_GNU
uint16_t __u6_addr16[8];
uint32_t __u6_addr32[4];
#endif
} __in6_u;
#define s6_addr __in6_u.__u6_addr8
#if defined __USE_MISC || defined __USE_GNU
# define s6_addr16 __in6_u.__u6_addr16
# define s6_addr32 __in6_u.__u6_addr32
#endif
};
#endif /* !__USE_KERNEL_IPV6_DEFS */
返回值
RETURN VALUE
returns 1 on success (network address was successfully converted).
returns 0 is returned if src does not contain a character string rep‐resenting a valid network address in the specified address family.
If af does not contain a valid address family, -1 is returned and errno is set to EAFNOSUPPORT.
IPV4代码示例:
// 测试IPv4
void testipv4()
{
/* convert buffer cache */
char buf[128] = {0};
char sip4[128] = "11.12.13.14";
struct in_addr address;
/* ip地址转网络字节序 */
int ret = inet_pton(AF_INET, (const char *)sip4, (void *)&(address));
if (ret != 1)
{
perror("inet_pton convert error.");
}
printf("address.s_addr:%d\tHEX:0X%x\n", address.s_addr, address.s_addr);
/* 网络字节序转ip地址 */
const char * result = inet_ntop(AF_INET, &address, buf, sizeof(buf));
if(!result)
{
perror("inet_ntop convert error.");
}
else
{
printf("buf:%s\n", buf);
printf("result:%s\n", result);
}
}
IPV6的代码示例
// 测试IPv6
void testipv6()
{
/* convert buffer cache */
char buf[128] = {0};
char sip6[128] = "2222:8888:6666:3333:1319:2222:3333:6666";
struct in6_addr address;
int ret = inet_pton(AF_INET6, (const char *)sip6, (void *)&(address));
if (ret != 1)
{
perror("inet_pton convert error.");
}
const char * result = inet_ntop(AF_INET6, (void *)&address, buf, sizeof(buf));
if(!result)
{
perror("inet_ntop convert error.");
}
else
{
printf("buf:%s\n", buf);
printf("result:%s\n", result);
}
}
使用联合体的方式合理的使用地址转换函数
需求:对于下面的结构体 如果是IPv4地址 放在m_sip的后4字节.
typedef struct NP_FLEX_RULE_TX_TABLE_KEY_T
{
UCHAR m_sip[16]; /* 16B */
UCHAR m_dip[16]; /* 16B */
USHORT m_sport; /* 2B */
USHORT m_dport; /* 2B */
UINT8 m_proto; /* 1B */
UINT8 m_mode; /* 1B */
}__attribute__((packed)) NP_FLEX_RULE_TX_TABLE_KEY_T;
解决方案:
1.定义联合体16Bytes
typedef union
{
uint8_t v6[16];
uint32_t v4[4];
uint64_t v64[2];
} IP_ADDR_T;
void testIP()
{
int ret = 0;
char buf[128] = {0};
/* loop variable */
int idx = 0;
char sip4[128] = "11.12.13.14";
char sip6[128] = "2222:8888:6666:3333:1319:2222:3333:6666";
NP_FLEX_RULE_TX_TABLE_KEY_T key;
memset(&key, 0, sizeof(NP_FLEX_RULE_TX_TABLE_KEY_T));
/* 使用联合体 */
IP_ADDR_T address;
memset(&address, 0, sizeof(IP_ADDR_T));
IPTYPE iptype = appointIP(sip6);
if (iptype == NEITHER)
{
perror("ip address invaild.\n");
return;
}
else if(iptype == IP4)
{
ret = inet_pton(AF_INET, (const char *)sip4, (void *)&(address));
if (ret != 1)
{
perror("inet_pton convert error.");
}
key.m_mode = IP4;
memcpy(key.m_sip + 12, &(address.v4[0]), sizeof(uint8_t) * 4);
for(idx = 0; idx < 4; ++idx)
{
printf("address.v4[%d]:0X%x\n", idx, address.v4[idx]);
}
}
else if(iptype == IP6)
{
ret = inet_pton(AF_INET6, (const char *)sip6, (void *)&(address));
if (ret != 1)
{
perror("inet_pton convert error.");
}
key.m_mode = IP6;
memcpy(key.m_sip, address.v6, sizeof(uint8_t) * 16);
for(idx = 0; idx < 4; ++idx)
{
printf("0X%x\t", address.v4[idx]);
}
printf("\n");
}
uint8_t mode = key.m_mode;
if (mode == IP4)
{
const char * result = inet_ntop(AF_INET, &(address.v4[0]), buf, sizeof(buf));
if(!result)
{
perror("inet_ntop convert error.");
}
else
{
printf("buf:%s\n", buf);
printf("result:%s\n", result);
}
}
else if(mode == IP6)
{
const char * result = inet_ntop(AF_INET6, (void *)&address, buf, sizeof(buf));
if(!result)
{
perror("inet_ntop convert error.");
}
else
{
printf("buf:%s\n", buf);
printf("result:%s\n", result);
}
}
}