@@ -205,6 +205,9 @@ bool ipv4_address::unit_test(FILE *output) { // output=nullptr by default
205205 return all_passed;
206206}
207207
208+
209+ using ipv6_array_t = std::array<uint8_t , 16 >;
210+
208211// / an IP version six address in network byte order. This class
209212// / represents a raw (binary) address; to parse a textual
210213// / representation of an IPv6 address, use \ref ipv6_address_string.
@@ -307,11 +310,7 @@ struct ipv6_address {
307310 multicast
308311 };
309312
310- // bool is_global_unicast() const {
311- // return (a & 0xe0000000) == 0x20000000;
312- // }
313313 bool is_global_unicast () const {
314- // fprintf(stderr, "check: %08x\t%08x==%08x\n", a, (a & hton<uint32_t>(0xe0000000)), hton<uint32_t>(0x20000000));
315314 return (a[0 ] & hton<uint32_t >(0xe0000000 )) == hton<uint32_t >(0x20000000 );
316315 }
317316 bool is_unique_local_unicast () const {
@@ -327,7 +326,7 @@ struct ipv6_address {
327326 return (a[0 ] & hton<uint32_t >(0xff000000 )) == hton<uint32_t >(0xff000000 );
328327 }
329328 bool is_global () const {
330- return is_global_unicast (); // TODO: consider global multicast
329+ return is_global_unicast () || is_ipv4_mapped ();
331330 }
332331 bool is_ipv4_mapped () const {
333332 return (a[0 ] == 0 && a[1 ] == 0 && a[2 ] == hton<uint32_t >(0x0000ffff ));
@@ -337,6 +336,20 @@ struct ipv6_address {
337336
338337};
339338
339+ // hasher for ipv6_address
340+ //
341+ namespace std {
342+ template <>
343+ struct hash <ipv6_address> {
344+ std::size_t operator ()(const ipv6_address& addr) const {
345+ return std::hash<uint32_t >{}(addr.a [0 ])
346+ ^ std::hash<uint32_t >{}(addr.a [1 ])
347+ ^ std::hash<uint32_t >{}(addr.a [2 ])
348+ ^ std::hash<uint32_t >{}(addr.a [3 ]);
349+ }
350+ };
351+ }
352+
340353inline bool ipv6_address::unit_test () {
341354
342355 // ipv6_address addr;
@@ -384,16 +397,18 @@ namespace normalized {
384397 static const ipv6_address ipv6_unique_local{0x000000fd , 0x00000000 , 0x00000000 , 0x01000000 };
385398};
386399
387- inline void normalize (ipv4_address &a) {
400+ inline ipv4_address normalize (const ipv4_address &a) {
388401 if (!a.is_global ()) {
389- a = normalized::ipv4_private_use;
402+ return normalized::ipv4_private_use;
390403 }
404+ return a;
391405}
392406
393- inline void normalize (ipv6_address &a) {
407+ inline ipv6_address normalize (const ipv6_address &a) {
394408 if (!a.is_global ()) {
395- a = normalized::ipv6_unique_local;
409+ return normalized::ipv6_unique_local;
396410 }
411+ return a;
397412}
398413
399414struct ip_address {
@@ -543,8 +558,6 @@ T hex_str_to_uint(const hex_digits &d) {
543558}
544559
545560
546- using ipv6_array_t = std::array<uint8_t , 16 >;
547-
548561static inline void ipv6_array_print (FILE *f, ipv6_array_t ipv6) {
549562 fprintf (f,
550563 " %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" ,
@@ -865,6 +878,11 @@ class ipv6_address_string {
865878 return x;
866879 }
867880
881+ ipv6_address get_address () const {
882+ ipv6_array_t arry = get_value_array ();
883+ return get_ipv6_address (arry);
884+ }
885+
868886 // unit_test() is a static function that performs a unit test of
869887 // this class, using the example addresses from RFC 4291. It
870888 // returns true if all tests pass, and false otherwise.
0 commit comments