diff options
-rw-r--r-- | lib/socket.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/socket.c b/lib/socket.c index cf7b6aa..e313f8b 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -854,7 +854,7 @@ xclose(int *fdptr) typedef struct { const char *name; - enum { DT_SIGNED, DT_UNSIGNED, DT_IPV4ADDR, DT_CALLBACK } type; + enum { DT_SIGNED, DT_UNSIGNED, DT_IPV4ADDR, DT_IPV6ADDR, DT_CALLBACK } type; union { size_t offset; bool (*to_c)(void *, uc_value_t *); @@ -1381,6 +1381,17 @@ uv_to_struct(uc_value_t *uv, struct_t *spec) break; + case DT_IPV6ADDR: + s = ucv_string_get(fv); + + if (!s || inet_pton(AF_INET6, s, st + m->u1.offset) != 1) { + free(st); + err_return(EINVAL, + "Unable to convert field %s to IPv6 address", m->name); + } + + break; + case DT_CALLBACK: if (m->u1.to_c && !m->u1.to_c(st, fv)) { free(st); @@ -1397,7 +1408,7 @@ uv_to_struct(uc_value_t *uv, struct_t *spec) static uc_value_t * struct_to_uv(char *st, struct_t *spec) { - char s[sizeof("255.255.255.255")]; + char s[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; uc_value_t *uv, *fv; member_t *m; @@ -1456,6 +1467,12 @@ struct_to_uv(char *st, struct_t *spec) break; + case DT_IPV6ADDR: + if (inet_ntop(AF_INET6, st + m->u1.offset, s, sizeof(s))) + fv = ucv_string_new(s); + + break; + case DT_CALLBACK: fv = m->u2.to_uv ? m->u2.to_uv(st) : NULL; break; |