Home | History | Annotate | Download | only in base
      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 
     17 IPEndPoint::IPEndPoint() : port_(0) {}
     18 
     19 IPEndPoint::~IPEndPoint() {}
     20 
     21 IPEndPoint::IPEndPoint(const IPAddressNumber& address, int port)
     22     : address_(address),
     23       port_(port) {}
     24 
     25 IPEndPoint::IPEndPoint(const IPEndPoint& endpoint) {
     26   address_ = endpoint.address_;
     27   port_ = endpoint.port_;
     28 }
     29 
     30 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 
     45 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 
     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 
    109 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 
    119 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 
    130 bool IPEndPoint::operator==(const IPEndPoint& that) const {
    131   return address_ == that.address_ && port_ == that.port_;
    132 }
    133 
    134 }  // namespace net
    135