1 // Copyright (c) 2011 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.
4
5 #include "net/base/ip_endpoint.h"
6
7 #include "base/logging.h"
8 #include "base/string_number_conversions.h"
9 #if defined(OS_WIN)
10 #include <winsock2.h>
11 #elif defined(OS_POSIX)
12 #include <netinet/in.h>
13 #endif
14
15 namespace net {
16
IPEndPoint()17 IPEndPoint::IPEndPoint() : port_(0) {}
18
~IPEndPoint()19 IPEndPoint::~IPEndPoint() {}
20
IPEndPoint(const IPAddressNumber & address,int port)21 IPEndPoint::IPEndPoint(const IPAddressNumber& address, int port)
22 : address_(address),
23 port_(port) {}
24
IPEndPoint(const IPEndPoint & endpoint)25 IPEndPoint::IPEndPoint(const IPEndPoint& endpoint) {
26 address_ = endpoint.address_;
27 port_ = endpoint.port_;
28 }
29
GetFamily() const30 int IPEndPoint::GetFamily() const {
31 switch (address_.size()) {
32 case kIPv4AddressSize: {
33 return AF_INET;
34 }
35 case kIPv6AddressSize: {
36 return AF_INET6;
37 }
38 default: {
39 NOTREACHED() << "Bad IP address";
40 return AF_UNSPEC;
41 }
42 }
43 }
44
ToSockAddr(struct sockaddr * address,size_t * address_length) const45 bool IPEndPoint::ToSockAddr(struct sockaddr* address,
46 size_t* address_length) const {
47 DCHECK(address);
48 DCHECK(address_length);
49 switch (address_.size()) {
50 case kIPv4AddressSize: {
51 if (*address_length < sizeof(struct sockaddr_in))
52 return false;
53 *address_length = sizeof(struct sockaddr_in);
54 struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(address);
55 memset(addr, 0, sizeof(struct sockaddr_in));
56 addr->sin_family = AF_INET;
57 addr->sin_port = htons(port_);
58 memcpy(&addr->sin_addr, &address_[0], kIPv4AddressSize);
59 break;
60 }
61 case kIPv6AddressSize: {
62 if (*address_length < sizeof(struct sockaddr_in6))
63 return false;
64 *address_length = sizeof(struct sockaddr_in6);
65 struct sockaddr_in6* addr6 =
66 reinterpret_cast<struct sockaddr_in6*>(address);
67 memset(addr6, 0, sizeof(struct sockaddr_in6));
68 addr6->sin6_family = AF_INET6;
69 addr6->sin6_port = htons(port_);
70 memcpy(&addr6->sin6_addr, &address_[0], kIPv6AddressSize);
71 break;
72 }
73 default: {
74 NOTREACHED() << "Bad IP address";
75 break;
76 }
77 }
78 return true;
79 }
80
FromSockAddr(const struct sockaddr * address,size_t address_length)81 bool IPEndPoint::FromSockAddr(const struct sockaddr* address,
82 size_t address_length) {
83 DCHECK(address);
84 switch (address->sa_family) {
85 case AF_INET: {
86 const struct sockaddr_in* addr =
87 reinterpret_cast<const struct sockaddr_in*>(address);
88 port_ = ntohs(addr->sin_port);
89 const char* bytes = reinterpret_cast<const char*>(&addr->sin_addr);
90 address_.assign(&bytes[0], &bytes[kIPv4AddressSize]);
91 break;
92 }
93 case AF_INET6: {
94 const struct sockaddr_in6* addr =
95 reinterpret_cast<const struct sockaddr_in6*>(address);
96 port_ = ntohs(addr->sin6_port);
97 const char* bytes = reinterpret_cast<const char*>(&addr->sin6_addr);
98 address_.assign(&bytes[0], &bytes[kIPv6AddressSize]);
99 break;
100 }
101 default: {
102 NOTREACHED() << "Bad IP address";
103 break;
104 }
105 }
106 return true;
107 }
108
ToString() const109 std::string IPEndPoint::ToString() const {
110 struct sockaddr_storage addr_storage;
111 size_t addr_len = sizeof(addr_storage);
112 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
113 if (!ToSockAddr(addr, &addr_len)) {
114 return "";
115 }
116 return NetAddressToStringWithPort(addr, addr_len);
117 }
118
operator <(const IPEndPoint & that) const119 bool IPEndPoint::operator<(const IPEndPoint& that) const {
120 // Sort IPv4 before IPv6.
121 if (address_.size() != that.address_.size()) {
122 return address_.size() < that.address_.size();
123 }
124 if (address_ != that.address_) {
125 return address_ < that.address_;
126 }
127 return port_ < that.port_;
128 }
129
operator ==(const IPEndPoint & that) const130 bool IPEndPoint::operator==(const IPEndPoint& that) const {
131 return address_ == that.address_ && port_ == that.port_;
132 }
133
134 } // namespace net
135