1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/base/ip_endpoint.h"
7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/sys_byteorder.h"
12 #elif defined(OS_POSIX)
13 #include <netinet/in.h>
19 // By definition, socklen_t is large enough to hold both sizes.
20 const socklen_t kSockaddrInSize
= sizeof(struct sockaddr_in
);
21 const socklen_t kSockaddrIn6Size
= sizeof(struct sockaddr_in6
);
24 IPEndPoint::IPEndPoint() : port_(0) {}
26 IPEndPoint::~IPEndPoint() {}
28 IPEndPoint::IPEndPoint(const IPAddressNumber
& address
, int port
)
32 IPEndPoint::IPEndPoint(const IPEndPoint
& endpoint
) {
33 address_
= endpoint
.address_
;
34 port_
= endpoint
.port_
;
37 AddressFamily
IPEndPoint::GetFamily() const {
38 return GetAddressFamily(address_
);
41 int IPEndPoint::GetSockAddrFamily() const {
42 switch (address_
.size()) {
43 case kIPv4AddressSize
:
45 case kIPv6AddressSize
:
48 NOTREACHED() << "Bad IP address";
53 bool IPEndPoint::ToSockAddr(struct sockaddr
* address
,
54 socklen_t
* address_length
) const {
56 DCHECK(address_length
);
57 switch (address_
.size()) {
58 case kIPv4AddressSize
: {
59 if (*address_length
< kSockaddrInSize
)
61 *address_length
= kSockaddrInSize
;
62 struct sockaddr_in
* addr
= reinterpret_cast<struct sockaddr_in
*>(address
);
63 memset(addr
, 0, sizeof(struct sockaddr_in
));
64 addr
->sin_family
= AF_INET
;
65 addr
->sin_port
= base::HostToNet16(port_
);
66 memcpy(&addr
->sin_addr
, &address_
[0], kIPv4AddressSize
);
69 case kIPv6AddressSize
: {
70 if (*address_length
< kSockaddrIn6Size
)
72 *address_length
= kSockaddrIn6Size
;
73 struct sockaddr_in6
* addr6
=
74 reinterpret_cast<struct sockaddr_in6
*>(address
);
75 memset(addr6
, 0, sizeof(struct sockaddr_in6
));
76 addr6
->sin6_family
= AF_INET6
;
77 addr6
->sin6_port
= base::HostToNet16(port_
);
78 memcpy(&addr6
->sin6_addr
, &address_
[0], kIPv6AddressSize
);
87 bool IPEndPoint::FromSockAddr(const struct sockaddr
* sock_addr
,
88 socklen_t sock_addr_len
) {
94 if (!GetIPAddressFromSockAddr(sock_addr
, sock_addr_len
, &address
,
95 &address_len
, &port
)) {
99 address_
.assign(address
, address
+ address_len
);
104 std::string
IPEndPoint::ToString() const {
105 return IPAddressToStringWithPort(address_
, port_
);
108 std::string
IPEndPoint::ToStringWithoutPort() const {
109 return IPAddressToString(address_
);
112 bool IPEndPoint::operator<(const IPEndPoint
& that
) const {
113 // Sort IPv4 before IPv6.
114 if (address_
.size() != that
.address_
.size()) {
115 return address_
.size() < that
.address_
.size();
117 if (address_
!= that
.address_
) {
118 return address_
< that
.address_
;
120 return port_
< that
.port_
;
123 bool IPEndPoint::operator==(const IPEndPoint
& that
) const {
124 return address_
== that
.address_
&& port_
== that
.port_
;