• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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