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>
15 #include "net/base/net_util.h"
20 // By definition, socklen_t is large enough to hold both sizes.
21 const socklen_t kSockaddrInSize
= sizeof(struct sockaddr_in
);
22 const socklen_t kSockaddrIn6Size
= sizeof(struct sockaddr_in6
);
25 IPEndPoint::IPEndPoint() : port_(0) {}
27 IPEndPoint::~IPEndPoint() {}
29 IPEndPoint::IPEndPoint(const IPAddressNumber
& address
, uint16_t port
)
30 : address_(address
), port_(port
) {
33 IPEndPoint::IPEndPoint(const IPEndPoint
& endpoint
) {
34 address_
= endpoint
.address_
;
35 port_
= endpoint
.port_
;
38 AddressFamily
IPEndPoint::GetFamily() const {
39 return GetAddressFamily(address_
);
42 int IPEndPoint::GetSockAddrFamily() const {
43 switch (address_
.size()) {
44 case kIPv4AddressSize
:
46 case kIPv6AddressSize
:
49 NOTREACHED() << "Bad IP address";
54 bool IPEndPoint::ToSockAddr(struct sockaddr
* address
,
55 socklen_t
* address_length
) const {
57 DCHECK(address_length
);
58 switch (address_
.size()) {
59 case kIPv4AddressSize
: {
60 if (*address_length
< kSockaddrInSize
)
62 *address_length
= kSockaddrInSize
;
63 struct sockaddr_in
* addr
= reinterpret_cast<struct sockaddr_in
*>(address
);
64 memset(addr
, 0, sizeof(struct sockaddr_in
));
65 addr
->sin_family
= AF_INET
;
66 addr
->sin_port
= base::HostToNet16(port_
);
67 memcpy(&addr
->sin_addr
, &address_
[0], kIPv4AddressSize
);
70 case kIPv6AddressSize
: {
71 if (*address_length
< kSockaddrIn6Size
)
73 *address_length
= kSockaddrIn6Size
;
74 struct sockaddr_in6
* addr6
=
75 reinterpret_cast<struct sockaddr_in6
*>(address
);
76 memset(addr6
, 0, sizeof(struct sockaddr_in6
));
77 addr6
->sin6_family
= AF_INET6
;
78 addr6
->sin6_port
= base::HostToNet16(port_
);
79 memcpy(&addr6
->sin6_addr
, &address_
[0], kIPv6AddressSize
);
88 bool IPEndPoint::FromSockAddr(const struct sockaddr
* sock_addr
,
89 socklen_t sock_addr_len
) {
92 const uint8_t* address
;
95 if (!GetIPAddressFromSockAddr(sock_addr
, sock_addr_len
, &address
,
96 &address_len
, &port
)) {
100 address_
.assign(address
, address
+ address_len
);
105 std::string
IPEndPoint::ToString() const {
106 return IPAddressToStringWithPort(address_
, port_
);
109 std::string
IPEndPoint::ToStringWithoutPort() const {
110 return IPAddressToString(address_
);
113 bool IPEndPoint::operator<(const IPEndPoint
& that
) const {
114 // Sort IPv4 before IPv6.
115 if (address_
.size() != that
.address_
.size()) {
116 return address_
.size() < that
.address_
.size();
118 if (address_
!= that
.address_
) {
119 return address_
< that
.address_
;
121 return port_
< that
.port_
;
124 bool IPEndPoint::operator==(const IPEndPoint
& that
) const {
125 return address_
== that
.address_
&& port_
== that
.port_
;