写完之后才发现系统自带的inet_pton函数可以实现同样的功能,但好歹写完了,权当记录吧。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include<netinet/in.h>
#define ip6addr "2F19:123E:1234::2:1" // colon hexadecimal
typedef union{
unsigned char ucIp6[16];
unsigned short usIp6[8];
}unionIPV6;
char *strrev(char *str)
{
char *p1, *p2;
if (! str || ! *str)
return str;
for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
{
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return str;
}
int ip6str_parse(const char *point, unsigned short result[8]) {
for (int i = 0; i < 4; i++) {
result[i] = 0;
}
char buf[40] = {0}, revbuf[40];
int p = 0, q = 0;
strcpy(buf, point);
strcpy(revbuf, point);
strrev(revbuf);
buf[strlen(point)] = ':';
revbuf[strlen(point)] = ':';
for(int i = 0;i < 8; i++) {
q = strchr(buf+p, ':') - buf;
buf[q] = '\0';
result[i] = ntohs(strtol(buf+p, NULL, 16));
p = q + 1;
// if we find ::, then we should scan revbuf.2019:1::1 1::1:2019
if (buf[p] == ':') {
p = q = 0;
for (int j = 7;j > i;j--) {
q = strchr(revbuf+p, ':') - revbuf;
revbuf[q] = '\0';
strrev(revbuf+p);
result[j] = ntohs(strtol(revbuf+p, NULL, 16));
p = q + 1;
if (revbuf[p] == ':') {
break;
}
}
break;
}
}
return 1;
}
int main() {
unionIPV6 ip6 = {0};
ip6str_parse(ip6addr, ip6.usIp6);
for (int i = 0;i < 16 ; i++) {
printf("%p\r\n",ip6.ucIp6[i]);
}
return 0;
}