I have created my own function to convert ipv6 string into ipv6 value in array without the help of any external library like "boost".
It works for any format of ipv6 address.
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define PRINT_IPV6_STR "[%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x]"
#define PRINT_IPV6_VAL(ipaddr) ipaddr[0],ipaddr[1],ipaddr[2],ipaddr[3],ipaddr[4],ipaddr[5],ipaddr[6],ipaddr[7],ipaddr[8],ipaddr[9],ipaddr[10],ipaddr[11],ipaddr[12],ipaddr[13],ipaddr[14],ipaddr[15]
void getIpv6SubStr(const string inp, unsigned char* arr, unsigned char &dcolonIdx, unsigned char& arrIdxCnt)
{
unsigned char len=inp.size();
unsigned char j=0;
unsigned char k=0;
string t_str;
for(unsigned char i=0; i<=len-1; i++)
{
if(((i!=0) && (inp[i] == ':') && (inp[i-1] == ':')) ||
((i==0) && (inp[i] == ':') && (inp[i+1] == ':')))
{
dcolonIdx = k;
continue;
}
t_str[j++] = inp[i];
t_str[j]='\0';
if((inp[i] == ':') || (i==len-1))
{
unsigned short temp = stol (t_str,nullptr,16);
arr[k++] = temp>>8;
arr[k++] = temp;
j=0;
t_str.clear();
continue;
}
}
arrIdxCnt = k;
printf("\n Input-ipv6-str[%s] Ipv6-substr" PRINT_IPV6_STR " dcolonIdx[%d] arrIdxCnt[%d]",
inp.c_str(), PRINT_IPV6_VAL(arr), dcolonIdx,arrIdxCnt);
}
void convertIpv6StringToAddr(const string inp, unsigned char* arr)
{
unsigned char substr_arr[16] = {};
unsigned char dcolonIdx = 0xFF;
unsigned char arrIdxCnt = 0;
/* Get the rcvd ipv6 address */
getIpv6SubStr(inp, substr_arr, dcolonIdx, arrIdxCnt);
/* If doubleColon is not present in rcvd IPv6 address, then the parsed ipv6 address can be directly used */
if(dcolonIdx == 0xFF)
{
memcpy(arr, substr_arr, 16);
printf("\n Input-ipv6-str[%s] Converted-Ipv6-Addr-Val" PRINT_IPV6_STR,
inp.c_str(), PRINT_IPV6_VAL(arr));
return;
}
/**
* If doubleColon is present in rcvd IPv6 address, then we should repace it with required number of 0's
* For eg:
* - if rcvd ipv6 address is "a1:a2:a3::a6:a7:a8" then the output ipv6 should be
* "00a1:00a2:00a3:0000:0000:00a6:00a7:00a8"
* - if rcvd ipv6 address is "::124" then the output ipv6 should be
* "0000:0000:0000:0000:0000:0000:0000:0124"
*/
unsigned char idxZeros = 0;
/**
* if rcvd IPv6 address starts with doubleColon,
* find the number of indices which need to filled with Zeros.
* then from idx=0 fill zeros until the required idx, and then fill the rcvd ipv6 address
* eg: "::124" => "0000:0000:0000:0000:0000:0000:0000:0124"
*/
if(dcolonIdx == 0)
{
idxZeros = 16-arrIdxCnt;
memcpy(&arr[idxZeros], substr_arr, arrIdxCnt);
printf("\n Input-ipv6-str[%s] Converted-Ipv6-Addr-Val" PRINT_IPV6_STR,
inp.c_str(), PRINT_IPV6_VAL(arr));
return;
}
/**
* if rcvd IPv6 address contians doubleColon inbetween,
* find the number of indices which need to filled with Zeros and the position of doubleColon,
* then from the position of doubleColon fill zeros until the required idx, and fill the rcvd
* ipv6 address in its required indices
* eg: "a1:a2:a3::a6:a7:a8" => "00a1:00a2:00a3:0000:0000:00a6:00a7:00a8"
*/
idxZeros = 16-arrIdxCnt;
memcpy(arr, substr_arr, dcolonIdx);
memcpy(&arr[dcolonIdx+idxZeros], &substr_arr[dcolonIdx], arrIdxCnt-dcolonIdx);
printf("\n Input-ipv6-str[%s] Converted-Ipv6-Addr-Val" PRINT_IPV6_STR,
inp.c_str(), PRINT_IPV6_VAL(arr));
}
void test_ut(int i, string str)
{
printf("\n%d.",i);
unsigned char arr[16] = {};
convertIpv6StringToAddr(str, arr);
i++;
}
int main()
{
test_ut(1, "a1a2:b3b4:c5c6:d7d8:0000:e5:6f:0001");
test_ut(2, "a1");
test_ut(3, "a1::");
test_ut(4, "a1::1");
test_ut(5, "a1a2:b3b4:c5c6:d7d8::e5");
test_ut(6, "a1a2:b3b4:c5c6:d7d8::e5:6f:1");
test_ut(7, "::e5:0:678");
return 0;
}
output:
- Input-ipv6-str[a1a2:b3b4:c5c6:d7d8:0000:e5:6f:0001] Ipv6-substr[a1a2:b3b4:c5c6:d7d8:0000:00e5:006f:0001] dcolonIdx[255]
arrIdxCnt[16] Input-ipv6-str[a1a2:b3b4:c5c6:d7d8:0000:e5:6f:0001]
Converted-Ipv6-Addr-Val[a1a2:b3b4:c5c6:d7d8:0000:00e5:006f:0001]
- Input-ipv6-str[a1] Ipv6-substr[00a1:0000:0000:0000:0000:0000:0000:0000] dcolonIdx[255]
arrIdxCnt[2] Input-ipv6-str[a1]
Converted-Ipv6-Addr-Val[00a1:0000:0000:0000:0000:0000:0000:0000]
- Input-ipv6-str[a1::] Ipv6-substr[00a1:0000:0000:0000:0000:0000:0000:0000] dcolonIdx[2]
arrIdxCnt[2] Input-ipv6-str[a1::]
Converted-Ipv6-Addr-Val[00a1:0000:0000:0000:0000:0000:0000:0000]
- Input-ipv6-str[a1::1] Ipv6-substr[00a1:0001:0000:0000:0000:0000:0000:0000] dcolonIdx[2]
arrIdxCnt[4] Input-ipv6-str[a1::1]
Converted-Ipv6-Addr-Val[00a1:0000:0000:0000:0000:0000:0000:0001]
- Input-ipv6-str[a1a2:b3b4:c5c6:d7d8::e5] Ipv6-substr[a1a2:b3b4:c5c6:d7d8:00e5:0000:0000:0000] dcolonIdx[8]
arrIdxCnt[10] Input-ipv6-str[a1a2:b3b4:c5c6:d7d8::e5]
Converted-Ipv6-Addr-Val[a1a2:b3b4:c5c6:d7d8:0000:0000:0000:00e5]
- Input-ipv6-str[a1a2:b3b4:c5c6:d7d8::e5:6f:1] Ipv6-substr[a1a2:b3b4:c5c6:d7d8:00e5:006f:0001:0000] dcolonIdx[8]
arrIdxCnt[14] Input-ipv6-str[a1a2:b3b4:c5c6:d7d8::e5:6f:1]
Converted-Ipv6-Addr-Val[a1a2:b3b4:c5c6:d7d8:0000:00e5:006f:0001]
- Input-ipv6-str[::e5:0:678] Ipv6-substr[00e5:0000:0678:0000:0000:0000:0000:0000] dcolonIdx[0]
arrIdxCnt[6] Input-ipv6-str[::e5:0:678]
Converted-Ipv6-Addr-Val[0000:0000:0000:0000:0000:00e5:0000:0678]