|
14 | 14 |
|
15 | 15 | #define _GNU_SOURCE /* strndup */ |
16 | 16 |
|
| 17 | +#include "ipv6_common.h" |
17 | 18 | #include "plugins_internal.h" |
18 | 19 | #include "plugins_types.h" |
19 | 20 |
|
@@ -60,12 +61,13 @@ static void lyplg_type_free_ipv6_address(const struct ly_ctx *ctx, struct lyd_va |
60 | 61 | * @param[in] ctx libyang context with dictionary. |
61 | 62 | * @param[in,out] addr Allocated value for the address. |
62 | 63 | * @param[out] zone Ipv6 address zone in dictionary. |
| 64 | + * @param[out] dual stack format. |
63 | 65 | * @param[out] err Error information on error. |
64 | 66 | * @return LY_ERR value. |
65 | 67 | */ |
66 | 68 | static LY_ERR |
67 | 69 | ipv6address_str2ip(const char *value, uint32_t value_len, uint32_t options, const struct ly_ctx *ctx, |
68 | | - struct in6_addr *addr, const char **zone, struct ly_err_item **err) |
| 70 | + struct in6_addr *addr, const char **zone, uint8_t *dual_stack_format, struct ly_err_item **err) |
69 | 71 | { |
70 | 72 | LY_ERR ret = LY_SUCCESS; |
71 | 73 | const char *addr_no_zone; |
@@ -107,6 +109,9 @@ ipv6address_str2ip(const char *value, uint32_t value_len, uint32_t options, cons |
107 | 109 | goto cleanup; |
108 | 110 | } |
109 | 111 |
|
| 112 | + /* store dual stack IPv6 format or compressed format */ |
| 113 | + *dual_stack_format = ly_strnchr(value, '.', value_len) != NULL; |
| 114 | + |
110 | 115 | /* restore the value */ |
111 | 116 | if ((options & LYPLG_TYPE_STORE_DYNAMIC) && zone_ptr) { |
112 | 117 | *zone_ptr = '%'; |
@@ -174,7 +179,8 @@ lyplg_type_store_ipv6_address(const struct ly_ctx *ctx, const struct lysc_type * |
174 | 179 | LY_CHECK_GOTO(ret, cleanup); |
175 | 180 |
|
176 | 181 | /* get the network-byte order address */ |
177 | | - ret = ipv6address_str2ip(value, value_size, options, ctx, &val->addr, &val->zone, err); |
| 182 | + ret = ipv6address_str2ip(value, value_size, options, ctx, &val->addr, &val->zone, |
| 183 | + &val->dual_stack_format, err); |
178 | 184 | LY_CHECK_GOTO(ret, cleanup); |
179 | 185 |
|
180 | 186 | if (format == LY_VALUE_CANON) { |
@@ -258,6 +264,7 @@ lyplg_type_print_ipv6_address(const struct ly_ctx *ctx, const struct lyd_value * |
258 | 264 | struct lyd_value_ipv6_address *val; |
259 | 265 | uint32_t zone_len; |
260 | 266 | char *ret; |
| 267 | + LY_ERR rc; |
261 | 268 |
|
262 | 269 | LYD_VALUE_GET(value, val); |
263 | 270 |
|
@@ -290,15 +297,10 @@ lyplg_type_print_ipv6_address(const struct ly_ctx *ctx, const struct lyd_value * |
290 | 297 | if (!value->_canonical) { |
291 | 298 | /* '%' + zone */ |
292 | 299 | zone_len = val->zone ? strlen(val->zone) + 1 : 0; |
293 | | - ret = malloc(INET6_ADDRSTRLEN + zone_len); |
294 | | - LY_CHECK_RET(!ret, NULL); |
295 | 300 |
|
296 | | - /* get the address in string */ |
297 | | - if (!inet_ntop(AF_INET6, &val->addr, ret, INET6_ADDRSTRLEN)) { |
298 | | - free(ret); |
299 | | - LOGERR(ctx, LY_ESYS, "Failed to get IPv6 address in string (%s).", strerror(errno)); |
300 | | - return NULL; |
301 | | - } |
| 301 | + rc = ipv6address_ip2str(&val->addr, val->dual_stack_format, |
| 302 | + &ret, INET6_ADDRSTRLEN + zone_len); |
| 303 | + LY_CHECK_RET(!ret || rc != LY_SUCCESS, NULL); |
302 | 304 |
|
303 | 305 | /* add zone */ |
304 | 306 | if (zone_len) { |
|
0 commit comments