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