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.