extern struct setting_type setting_type_string __setting_type;
extern struct setting_type setting_type_uristring __setting_type;
extern struct setting_type setting_type_ipv4 __setting_type;
+extern struct setting_type setting_type_ipv6 __setting_type;
extern struct setting_type setting_type_int8 __setting_type;
extern struct setting_type setting_type_int16 __setting_type;
extern struct setting_type setting_type_int32 __setting_type;
.aton = ipv6_sock_aton,
};
+/**
+ * Parse IPv6 address setting value
+ *
+ * @v type Setting type
+ * @v value Formatted setting value
+ * @v buf Buffer to contain raw value
+ * @v len Length of buffer
+ * @ret len Length of raw value, or negative error
+ */
+static int parse_ipv6_setting ( struct setting_type *type __unused,
+ const char *value, void *buf, size_t len ) {
+ struct in6_addr ipv6;
+ int rc;
+
+ /* Parse IPv6 address */
+ if ( ( rc = inet6_aton ( value, &ipv6 ) ) != 0 )
+ return rc;
+
+ /* Copy to buffer */
+ if ( len > sizeof ( ipv6 ) )
+ len = sizeof ( ipv6 );
+ memcpy ( buf, &ipv6, len );
+
+ return ( sizeof ( ipv6 ) );
+}
+
+/**
+ * Format IPv6 address setting value
+ *
+ * @v type Setting type
+ * @v raw Raw setting value
+ * @v raw_len Length of raw setting value
+ * @v buf Buffer to contain formatted value
+ * @v len Length of buffer
+ * @ret len Length of formatted value, or negative error
+ */
+static int format_ipv6_setting ( struct setting_type *type __unused,
+ const void *raw, size_t raw_len, char *buf,
+ size_t len ) {
+ const struct in6_addr *ipv6 = raw;
+
+ if ( raw_len < sizeof ( *ipv6 ) )
+ return -EINVAL;
+ return snprintf ( buf, len, "%s", inet6_ntoa ( ipv6 ) );
+}
+
+/** An IPv6 address setting type */
+struct setting_type setting_type_ipv6 __setting_type = {
+ .name = "ipv6",
+ .parse = parse_ipv6_setting,
+ .format = format_ipv6_setting,
+};
+
/**
* Perform IPv6 stateless address autoconfiguration (SLAAC)
*
.type = &setting_type_ipv4,
};
+/** Test IPv6 address setting type */
+static struct setting test_ipv6_setting = {
+ .name = "test_ipv6",
+ .type = &setting_type_ipv6,
+};
+
/** Test signed 8-bit integer setting type */
static struct setting test_int8_setting = {
.name = "test_int8",
fetchf_ok ( &test_settings, &test_ipv4_setting,
RAW ( 212, 13, 204, 60 ), "212.13.204.60" );
+ /* "ipv6" setting type */
+ storef_ok ( &test_settings, &test_ipv6_setting,
+ "2001:ba8:0:1d4::6950:5845",
+ RAW ( 0x20, 0x01, 0x0b, 0xa8, 0x00, 0x00, 0x01, 0xd4,
+ 0x00, 0x00, 0x00, 0x00, 0x69, 0x50, 0x58, 0x45 ) );
+ fetchf_ok ( &test_settings, &test_ipv6_setting,
+ RAW ( 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x0c, 0x29, 0xff, 0xfe, 0xc5, 0x39, 0xa1 ),
+ "fe80::20c:29ff:fec5:39a1" );
+
/* Integer setting types (as formatted strings) */
storef_ok ( &test_settings, &test_int8_setting,
"54", RAW ( 54 ) );