ip_endpoint.cc revision dc0f95d653279beabeb9817299e2902918ba123e
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
14namespace net {
15
16const size_t kIPv4AddressSize = 4;
17const size_t kIPv6AddressSize = 16;
18
19IPEndPoint::IPEndPoint() : port_(0) {}
20
21IPEndPoint::~IPEndPoint() {}
22
23IPEndPoint::IPEndPoint(const IPAddressNumber& address, int port)
24    : address_(address),
25      port_(port) {}
26
27IPEndPoint::IPEndPoint(const IPEndPoint& endpoint) {
28  address_ = endpoint.address_;
29  port_ = endpoint.port_;
30}
31
32bool IPEndPoint::ToSockaddr(struct sockaddr* address,
33                            size_t* address_length) const {
34  DCHECK(address);
35  DCHECK(address_length);
36  switch (address_.size()) {
37    case kIPv4AddressSize: {
38      if (*address_length < sizeof(struct sockaddr_in))
39        return false;
40      *address_length = sizeof(struct sockaddr_in);
41      struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(address);
42      memset(addr, 0, sizeof(struct sockaddr_in));
43      addr->sin_family = AF_INET;
44      addr->sin_port = htons(port_);
45      memcpy(&addr->sin_addr, &address_[0], kIPv4AddressSize);
46      break;
47    }
48    case kIPv6AddressSize: {
49      if (*address_length < sizeof(struct sockaddr_in6))
50        return false;
51      *address_length = sizeof(struct sockaddr_in6);
52      struct sockaddr_in6* addr6 =
53          reinterpret_cast<struct sockaddr_in6*>(address);
54      memset(addr6, 0, sizeof(struct sockaddr_in6));
55      addr6->sin6_family = AF_INET6;
56      addr6->sin6_port = htons(port_);
57      memcpy(&addr6->sin6_addr, &address_[0], kIPv6AddressSize);
58      break;
59    }
60    default: {
61      NOTREACHED() << "Bad IP address";
62      break;
63    }
64  }
65  return true;
66}
67
68bool IPEndPoint::FromSockAddr(const struct sockaddr* address,
69                              size_t address_length) {
70  DCHECK(address);
71  switch (address->sa_family) {
72    case AF_INET: {
73      const struct sockaddr_in* addr =
74          reinterpret_cast<const struct sockaddr_in*>(address);
75      port_ = ntohs(addr->sin_port);
76      const char* bytes = reinterpret_cast<const char*>(&addr->sin_addr);
77      address_.assign(&bytes[0], &bytes[kIPv4AddressSize]);
78      break;
79    }
80    case AF_INET6: {
81      const struct sockaddr_in6* addr =
82          reinterpret_cast<const struct sockaddr_in6*>(address);
83      port_ = ntohs(addr->sin6_port);
84      const char* bytes = reinterpret_cast<const char*>(&addr->sin6_addr);
85      address_.assign(&bytes[0], &bytes[kIPv6AddressSize]);
86      break;
87    }
88    default: {
89      NOTREACHED() << "Bad IP address";
90      break;
91    }
92  }
93  return true;
94}
95
96bool IPEndPoint::operator<(const IPEndPoint& that) const {
97  return address_ < that.address_ || port_ < that.port_;
98}
99
100bool IPEndPoint::operator==(const IPEndPoint& that) const {
101  return address_ == that.address_ && port_ == that.port_;
102}
103
104}  // namespace net
105