Skip to content

Commit

Permalink
options/posix: Add support for IPv6 addresses in inet_pton
Browse files Browse the repository at this point in the history
Co-authored-by: 48cf <[email protected]>
  • Loading branch information
Dennisbonke and 48cf committed Dec 13, 2024
1 parent 4b21d4f commit 264c58c
Showing 1 changed file with 84 additions and 3 deletions.
87 changes: 84 additions & 3 deletions options/posix/generic/arpa-inet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ const char *inet_ntop(int af, const void *__restrict src, char *__restrict dst,
errno = ENOSPC;
return NULL;
}

int inet_pton(int af, const char *__restrict src, void *__restrict dst) {
switch (af) {
case AF_INET: {
Expand All @@ -200,9 +201,89 @@ int inet_pton(int af, const char *__restrict src, void *__restrict dst) {
addr->s_addr = htonl(ip);
break;
}
case AF_INET6:
mlibc::infoLogger() << "inet_pton: ipv6 is not implemented!" << frg::endlog;
/* fallthrough */
case AF_INET6: {
if(strchr(src, '.') != nullptr) {
mlibc::infoLogger() << "inet_pton: ipv4 in ipv6 address is not supported" << frg::endlog;
return 0;
}

const char *orig_src = src;
char *abbrev = strstr(src, "::");
if(abbrev && strstr(abbrev + 2, "::") != nullptr) {
return 0;
}

uint16_t addr[8] = {};
int len = abbrev ? abbrev - src : strlen(src);

int addr_len = 0;
while(*src && (src - orig_src) < len) {
char *end;
long int value = strtol(src, &end, 16);

if(value > 0xffff) {
return 0;
}
if(*end != '\0' && *end != ':') {
return 0;
}

src = end + 1;

if(addr_len >= 8) {
return 0;
}

addr[addr_len++] = htons(value);
}

if(abbrev) {
uint16_t array[8] = {};
int array_len = 0;

src = abbrev + 2;
while(*src) {
char *end;
long int value = strtol(src, &end, 16);

if(value > 0xffff) {
return 0;
}
if(*end != '\0' && *end != ':') {
return 0;
}

src = end + 1;

if(*end && !*src) {
return 0;
}
if(addr_len + array_len >= 8) {
return 0;
}

array[array_len++] = htons(value);
}

for(int i = 0; i < array_len; i++) {
addr[8 - array_len + i] = array[i];
}
} else if(addr_len != 8) {
return 0;
}

if(*src) {
return 0;
}

auto addr6 = reinterpret_cast<struct in6_addr*>(dst);

for(int i = 0; i < 8; i++) {
addr6->s6_addr16[i] = addr[i];
}

break;
}
default:
errno = EAFNOSUPPORT;
return -1;
Expand Down

0 comments on commit 264c58c

Please sign in to comment.