OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/base/ip_endpoint.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/strings/string_number_conversions.h" | |
9 #include "base/sys_byteorder.h" | |
10 #if defined(OS_WIN) | |
11 #include <winsock2.h> | |
12 #elif defined(OS_POSIX) | |
13 #include <netinet/in.h> | |
14 #endif | |
15 | |
16 namespace net { | |
17 | |
18 namespace { | |
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); | |
22 } | |
23 | |
24 IPEndPoint::IPEndPoint() : port_(0) {} | |
25 | |
26 IPEndPoint::~IPEndPoint() {} | |
27 | |
28 IPEndPoint::IPEndPoint(const IPAddressNumber& address, uint16 port) | |
29 : address_(address), | |
30 port_(port) {} | |
31 | |
32 IPEndPoint::IPEndPoint(const IPEndPoint& endpoint) { | |
33 address_ = endpoint.address_; | |
34 port_ = endpoint.port_; | |
35 } | |
36 | |
37 AddressFamily IPEndPoint::GetFamily() const { | |
38 return GetAddressFamily(address_); | |
39 } | |
40 | |
41 int IPEndPoint::GetSockAddrFamily() const { | |
42 switch (address_.size()) { | |
43 case kIPv4AddressSize: | |
44 return AF_INET; | |
45 case kIPv6AddressSize: | |
46 return AF_INET6; | |
47 default: | |
48 NOTREACHED() << "Bad IP address"; | |
49 return AF_UNSPEC; | |
50 } | |
51 } | |
52 | |
53 bool IPEndPoint::ToSockAddr(struct sockaddr* address, | |
54 socklen_t* address_length) const { | |
55 DCHECK(address); | |
56 DCHECK(address_length); | |
57 switch (address_.size()) { | |
58 case kIPv4AddressSize: { | |
59 if (*address_length < kSockaddrInSize) | |
60 return false; | |
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); | |
67 break; | |
68 } | |
69 case kIPv6AddressSize: { | |
70 if (*address_length < kSockaddrIn6Size) | |
71 return false; | |
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); | |
79 break; | |
80 } | |
81 default: | |
82 return false; | |
83 } | |
84 return true; | |
85 } | |
86 | |
87 bool IPEndPoint::FromSockAddr(const struct sockaddr* sock_addr, | |
88 socklen_t sock_addr_len) { | |
89 DCHECK(sock_addr); | |
90 | |
91 const uint8* address; | |
92 size_t address_len; | |
93 uint16 port; | |
94 if (!GetIPAddressFromSockAddr(sock_addr, sock_addr_len, &address, | |
95 &address_len, &port)) { | |
96 return false; | |
97 } | |
98 | |
99 address_.assign(address, address + address_len); | |
100 port_ = port; | |
101 return true; | |
102 } | |
103 | |
104 std::string IPEndPoint::ToString() const { | |
105 return IPAddressToStringWithPort(address_, port_); | |
106 } | |
107 | |
108 std::string IPEndPoint::ToStringWithoutPort() const { | |
109 return IPAddressToString(address_); | |
110 } | |
111 | |
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(); | |
116 } | |
117 if (address_ != that.address_) { | |
118 return address_ < that.address_; | |
119 } | |
120 return port_ < that.port_; | |
121 } | |
122 | |
123 bool IPEndPoint::operator==(const IPEndPoint& that) const { | |
124 return address_ == that.address_ && port_ == that.port_; | |
125 } | |
126 | |
127 } // namespace net | |
OLD | NEW |