[email protected] | 76ff86a | 2011-03-04 03:21:31 | [diff] [blame] | 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 | #if defined(OS_WIN) |
| 9 | #include <winsock2.h> |
| 10 | #elif defined(OS_POSIX) |
| 11 | #include <netinet/in.h> |
| 12 | #endif |
| 13 | |
| 14 | namespace net { |
| 15 | |
| 16 | const size_t kIPv4AddressSize = 4; |
| 17 | const size_t kIPv6AddressSize = 16; |
| 18 | |
| 19 | IPEndPoint::IPEndPoint() : port_(0) {} |
| 20 | |
[email protected] | 034714b | 2011-03-04 04:09:14 | [diff] [blame] | 21 | IPEndPoint::~IPEndPoint() {} |
| 22 | |
[email protected] | 76ff86a | 2011-03-04 03:21:31 | [diff] [blame] | 23 | IPEndPoint::IPEndPoint(const IPAddressNumber& address, int port) |
| 24 | : address_(address), |
| 25 | port_(port) {} |
| 26 | |
| 27 | IPEndPoint::IPEndPoint(const IPEndPoint& endpoint) { |
| 28 | address_ = endpoint.address_; |
| 29 | port_ = endpoint.port_; |
| 30 | } |
| 31 | |
[email protected] | 43d4a026 | 2011-03-09 19:26:04 | [diff] [blame^] | 32 | int IPEndPoint::GetFamily() const { |
| 33 | switch (address_.size()) { |
| 34 | case kIPv4AddressSize: { |
| 35 | return AF_INET; |
| 36 | } |
| 37 | case kIPv6AddressSize: { |
| 38 | return AF_INET6; |
| 39 | } |
| 40 | default: { |
| 41 | NOTREACHED() << "Bad IP address"; |
| 42 | return AF_INET; |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | bool IPEndPoint::ToSockAddr(struct sockaddr* address, |
[email protected] | 76ff86a | 2011-03-04 03:21:31 | [diff] [blame] | 48 | size_t* address_length) const { |
| 49 | DCHECK(address); |
| 50 | DCHECK(address_length); |
| 51 | switch (address_.size()) { |
| 52 | case kIPv4AddressSize: { |
| 53 | if (*address_length < sizeof(struct sockaddr_in)) |
| 54 | return false; |
| 55 | *address_length = sizeof(struct sockaddr_in); |
| 56 | struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(address); |
| 57 | memset(addr, 0, sizeof(struct sockaddr_in)); |
| 58 | addr->sin_family = AF_INET; |
| 59 | addr->sin_port = htons(port_); |
| 60 | memcpy(&addr->sin_addr, &address_[0], kIPv4AddressSize); |
| 61 | break; |
| 62 | } |
| 63 | case kIPv6AddressSize: { |
| 64 | if (*address_length < sizeof(struct sockaddr_in6)) |
| 65 | return false; |
| 66 | *address_length = sizeof(struct sockaddr_in6); |
| 67 | struct sockaddr_in6* addr6 = |
| 68 | reinterpret_cast<struct sockaddr_in6*>(address); |
| 69 | memset(addr6, 0, sizeof(struct sockaddr_in6)); |
| 70 | addr6->sin6_family = AF_INET6; |
| 71 | addr6->sin6_port = htons(port_); |
| 72 | memcpy(&addr6->sin6_addr, &address_[0], kIPv6AddressSize); |
| 73 | break; |
| 74 | } |
| 75 | default: { |
| 76 | NOTREACHED() << "Bad IP address"; |
| 77 | break; |
| 78 | } |
| 79 | } |
| 80 | return true; |
| 81 | } |
| 82 | |
| 83 | bool IPEndPoint::FromSockAddr(const struct sockaddr* address, |
| 84 | size_t address_length) { |
| 85 | DCHECK(address); |
| 86 | switch (address->sa_family) { |
| 87 | case AF_INET: { |
| 88 | const struct sockaddr_in* addr = |
| 89 | reinterpret_cast<const struct sockaddr_in*>(address); |
| 90 | port_ = ntohs(addr->sin_port); |
| 91 | const char* bytes = reinterpret_cast<const char*>(&addr->sin_addr); |
| 92 | address_.assign(&bytes[0], &bytes[kIPv4AddressSize]); |
| 93 | break; |
| 94 | } |
| 95 | case AF_INET6: { |
| 96 | const struct sockaddr_in6* addr = |
| 97 | reinterpret_cast<const struct sockaddr_in6*>(address); |
| 98 | port_ = ntohs(addr->sin6_port); |
| 99 | const char* bytes = reinterpret_cast<const char*>(&addr->sin6_addr); |
| 100 | address_.assign(&bytes[0], &bytes[kIPv6AddressSize]); |
| 101 | break; |
| 102 | } |
| 103 | default: { |
| 104 | NOTREACHED() << "Bad IP address"; |
| 105 | break; |
| 106 | } |
| 107 | } |
| 108 | return true; |
| 109 | } |
| 110 | |
| 111 | bool IPEndPoint::operator<(const IPEndPoint& that) const { |
| 112 | return address_ < that.address_ || port_ < that.port_; |
| 113 | } |
| 114 | |
| 115 | bool IPEndPoint::operator==(const IPEndPoint& that) const { |
| 116 | return address_ == that.address_ && port_ == that.port_; |
| 117 | } |
| 118 | |
| 119 | } // namespace net |