Because I see it again and again (to highlight it: I mean in NEW software):
- you MUST use sockaddr, sockaddr_in and sockaddr_in6 since the beginning.Don't use uint32_t or even worse unsigned long for IPv4 storage. But as you realize this is not protocol independent: sockaddr_in and sockaddr_in6 are container for IPv4(IP Version 4) and IPv6(IP Version 6). You will end up in switch/case statements to distinguish between both protocols. The superior solution is to use struct sockaddr_storage (big enough to also handle UNIX sockets). Currently there is nearly no excuse to use the protocol dependent containers. There are a few exceptions where (e.g. where sockaddr_storage will eat up to much memory) but this is really, really rare.
- gethostbyname() and gethostbyaddr() must be replaced (and also getipnodebyname and getipnodebyaddr)
- MUST also be replaced inet_ntop(), inet_pton() and inet_aton() (e.g. they they do not support scoped IPv6 address)
- in6_addr isn't guaranteed sufficient to identify a node. The scope information (the interface information) is missing
- Name resolution? use getaddrinfo() and getnameinfo()!
and last but not least: do not hardcode AF_INET or AF_INET6!