Notable difference from sockaddr_in(IPv4 address/port storage) is that it has scope id. Scope id denotes a ethernet interface in a system. Scope id binds IP address shown in sockaddr_in6 to specific ethernet interface. That binding is necessary because some IPv6 addresses are limited to an ethernet interface. Google about 'link local address' would be helpful.
+Tentative unified address class is as follows
+
+{code}
+class IpAddr
+{
+ sockaddr_in6 storage;
+
+ unsigned char* get_addr() {
+ // field name of in6_addr is different from platform to platform
+ return (unsigned char*)&storage.sin6_addr;
+ }
+
+ unsigned int& get_addr_header() { return *(unsigned int*)get_addr(); }
+ unsigned int& get_v4_addr() { return *(unsigned int*)(get_addr()+12); }
+
+public:
+ IpAddr()
+ {
+ memset(&storage, 0, sizeof(storage));
+ }
+
+ IpAddr(int ip, unsigned port = 0) : IpAddr()
+ {
+ storage.sin6_family = AF_INET;
+ storage.sin6_port = htons(port);
+ // IPv4-mapped region
+ get_addr_header() = 0xffff0000;
+ get_v4_addr() = (unsigned int)ip;
+ }
+
+ IpAddr(in_addr ip, unsigned port = 0) : IpAddr(ip.S_un.S_addr, port)
+ {
+ }
+
+ IpAddr(sockaddr_in* sin) : IpAddr(sin->sin_addr, sin->sin_port)
+ {
+ }
+
+ IpAddr(sockaddr_in6* sin6)
+ {
+ storage = *sin6;
+ }
+
+ sockaddr_in to_sin()
+ {
+ sockaddr_in ret;
+ memset(&ret, 0, sizeof(ret));
+ if (storage.sin_family != AF_INET) {
+ // error..
+ return ret;
+ }
+
+ ret.sin_family = AF_INET;
+ ret.sin_port = storage.sin6_port;
+ ret.sin_addr.S_un.S_addr = get_v4_addr();
+ }
+
+};
+
+{endcode}
+
+As you see here, sockaddr_in6 is super-set of sockaddr_in. So, this implementation considers IPv6 as basis and providing compatibility to IPv4 usage.
+
+There should be issue when a compiler does not have IPv6 related header files. In that case, we may supply definition of sockaddr_in6. Here only dependency is to AF_INET6 constant and struct sockaddr_in6.
+
+In IPv6, you cannot simply have 16byte IP address portion. You should have scope id as well. Separating { IP address, scope id } and port number could be possible but it will only make source codes complex. Some might argue that in this way, we could save some memory foot-print but I might say that considering size of sockaddr_in6, it is no big deal.
+
+In bottom line, I recommend you to have class IpPort (which is basically sockaddr_in6 with helper function) even you only want IP address.
+
{section: Todo}
Manageable daily work-list.