2 ** \file Ipv6Address.cpp
4 ** \author grymse@alhem.net
7 Copyright (C) 2007 Anders Hedstrom
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "Ipv6Address.h"
33 #ifdef SOCKETS_NAMESPACE
34 namespace SOCKETS_NAMESPACE
{
38 Ipv6Address::Ipv6Address(port_t port
) : m_valid(true)
40 memset(&m_addr
, 0, sizeof(m_addr
));
41 m_addr
.sin6_family
= AF_INET6
;
42 m_addr
.sin6_port
= htons( port
);
46 Ipv6Address::Ipv6Address(struct in6_addr
& a
,port_t port
) : m_valid(true)
48 memset(&m_addr
, 0, sizeof(m_addr
));
49 m_addr
.sin6_family
= AF_INET6
;
50 m_addr
.sin6_port
= htons( port
);
55 Ipv6Address::Ipv6Address(const std::string
& host
,port_t port
) : m_valid(false)
57 memset(&m_addr
, 0, sizeof(m_addr
));
58 m_addr
.sin6_family
= AF_INET6
;
59 m_addr
.sin6_port
= htons( port
);
62 if (Utility::u2ip(host
, a
))
71 Ipv6Address::Ipv6Address(struct sockaddr_in6
& sa
)
74 m_valid
= sa
.sin6_family
== AF_INET6
;
78 Ipv6Address::~Ipv6Address()
83 Ipv6Address::operator struct sockaddr
*()
85 return (struct sockaddr
*)&m_addr
;
89 Ipv6Address::operator socklen_t()
91 return sizeof(struct sockaddr_in6
);
95 void Ipv6Address::SetPort(port_t port
)
97 m_addr
.sin6_port
= htons( port
);
101 port_t
Ipv6Address::GetPort()
103 return ntohs( m_addr
.sin6_port
);
107 bool Ipv6Address::Resolve(const std::string
& hostname
,struct in6_addr
& a
)
109 struct sockaddr_in6 sa
;
110 memset(&a
, 0, sizeof(a
));
111 if (Utility::isipv6(hostname
))
113 if (!Utility::u2ip(hostname
, sa
, AI_NUMERICHOST
))
118 if (!Utility::u2ip(hostname
, sa
))
125 bool Ipv6Address::Reverse(struct in6_addr
& a
,std::string
& name
)
127 struct sockaddr_in6 sa
;
128 memset(&sa
, 0, sizeof(sa
));
129 sa
.sin6_family
= AF_INET6
;
131 return Utility::reverse((struct sockaddr
*)&sa
, sizeof(sa
), name
);
135 std::string
Ipv6Address::Convert(bool include_port
)
138 return Convert(m_addr
.sin6_addr
) + ":" + Utility::l2string(GetPort());
139 return Convert(m_addr
.sin6_addr
);
143 std::string
Ipv6Address::Convert(struct in6_addr
& a
,bool mixed
)
145 char slask
[100]; // l2ip temporary
147 unsigned int prev
= 0;
148 bool skipped
= false;
149 bool ok_to_skip
= true;
153 unsigned short addr16
[8];
154 memcpy(addr16
, &a
, sizeof(addr16
));
155 for (size_t i
= 0; i
< 6; i
++)
157 x
= ntohs(addr16
[i
]);
158 if (*slask
&& (x
|| !ok_to_skip
|| prev
))
160 if (x
|| !ok_to_skip
)
162 sprintf(slask
+ strlen(slask
),"%x", x
);
172 x
= ntohs(addr16
[6]);
173 sprintf(slask
+ strlen(slask
),":%u.%u",x
/ 256,x
& 255);
174 x
= ntohs(addr16
[7]);
175 sprintf(slask
+ strlen(slask
),".%u.%u",x
/ 256,x
& 255);
179 struct sockaddr_in6 sa
;
180 memset(&sa
, 0, sizeof(sa
));
181 sa
.sin6_family
= AF_INET6
;
184 Utility::reverse((struct sockaddr
*)&sa
, sizeof(sa
), name
, NI_NUMERICHOST
);
191 void Ipv6Address::SetAddress(struct sockaddr
*sa
)
193 memcpy(&m_addr
, sa
, sizeof(struct sockaddr_in6
));
197 int Ipv6Address::GetFamily()
199 return m_addr
.sin6_family
;
203 void Ipv6Address::SetFlowinfo(uint32_t x
)
205 m_addr
.sin6_flowinfo
= x
;
209 uint32_t Ipv6Address::GetFlowinfo()
211 return m_addr
.sin6_flowinfo
;
216 void Ipv6Address::SetScopeId(uint32_t x
)
218 m_addr
.sin6_scope_id
= x
;
222 uint32_t Ipv6Address::GetScopeId()
224 return m_addr
.sin6_scope_id
;
229 bool Ipv6Address::IsValid()
235 bool Ipv6Address::operator==(SocketAddress
& a
)
237 if (a
.GetFamily() != GetFamily())
239 if ((socklen_t
)a
!= sizeof(m_addr
))
241 struct sockaddr
*sa
= a
;
242 struct sockaddr_in6
*p
= (struct sockaddr_in6
*)sa
;
243 if (p
-> sin6_port
!= m_addr
.sin6_port
)
245 if (memcmp(&p
-> sin6_addr
, &m_addr
.sin6_addr
, sizeof(struct in6_addr
)))
251 std::auto_ptr
<SocketAddress
> Ipv6Address::GetCopy()
253 return std::auto_ptr
<SocketAddress
>(new Ipv6Address(m_addr
));
257 std::string
Ipv6Address::Reverse()
260 Reverse(m_addr
.sin6_addr
, tmp
);
265 #ifdef SOCKETS_NAMESPACE
266 } // namespace SOCKETS_NAMESPACE {
268 #endif // IPPROTO_IPV6
269 #endif // ENABLE_IPV6