Tentative unified address class is as follows
{code}
-class IpAddr
+
+#ifndef CONDOR_IPADDRESS_H
+#define CONDOR_IPADDRESS_H
+
+class ipaddr
{
sockaddr_in6 storage;
+ const unsigned char* get_addr() const {
+ // field name of in6_addr is different from platform to platform
+ return (const unsigned char*)&storage.sin6_addr;
+ }
+
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(); }
+ const unsigned int& get_v4_addr() const { return *(const unsigned int*)(get_addr()+12); }
unsigned int& get_v4_addr() { return *(unsigned int*)(get_addr()+12); }
public:
- IpAddr()
+ ipaddr()
{
memset(&storage, 0, sizeof(storage));
}
- IpAddr(int ip, unsigned port = 0) : IpAddr()
+ ipaddr(int ip, unsigned port = 0)
{
+ ipaddr();
storage.sin6_family = AF_INET;
storage.sin6_port = htons(port);
// IPv4-mapped region
@@ -142,35 +153,49 @@
get_v4_addr() = (unsigned int)ip;
}
- IpAddr(in_addr ip, unsigned port = 0) : IpAddr(ip.S_un.S_addr, port)
+ ipaddr(in_addr ip, unsigned port = 0)
{
+ ipaddr(ip.s_addr, port);
}
- IpAddr(sockaddr_in* sin) : IpAddr(sin->sin_addr, sin->sin_port)
+ ipaddr(sockaddr_in* sin)
{
+ ipaddr(sin->sin_addr, sin->sin_port);
}
- IpAddr(sockaddr_in6* sin6)
+ ipaddr(sockaddr_in6* sin6)
{
storage = *sin6;
}
- sockaddr_in to_sin()
+ sockaddr_in to_sin() const
{
sockaddr_in ret;
memset(&ret, 0, sizeof(ret));
- if (storage.sin_family != AF_INET) {
+ if (!is_ipv4()) {
// error..
return ret;
}
ret.sin_family = AF_INET;
ret.sin_port = storage.sin6_port;
- ret.sin_addr.S_un.S_addr = get_v4_addr();
+ ret.sin_addr.s_addr = get_v4_addr();
+ }
+
+ const sockaddr_in6& to_sin6() const
+ {
+ return storage;
+ }
+
+ bool is_ipv4() const
+ {
+ return storage.sin6_family == AF_INET;
}
};
+#endif
+
{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.