blob: 626d12e9895a14207b23a1aac9f57411ce69e66b [file] [log] [blame]
[email protected]76ff86a2011-03-04 03:21:311// 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
[email protected]034714b2011-03-04 04:09:1421IPEndPoint::~IPEndPoint() {}
22
[email protected]76ff86a2011-03-04 03:21:3123IPEndPoint::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
[email protected]43d4a0262011-03-09 19:26:0432int 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
47bool IPEndPoint::ToSockAddr(struct sockaddr* address,
[email protected]76ff86a2011-03-04 03:21:3148 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
83bool 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
111bool IPEndPoint::operator<(const IPEndPoint& that) const {
112 return address_ < that.address_ || port_ < that.port_;
113}
114
115bool IPEndPoint::operator==(const IPEndPoint& that) const {
116 return address_ == that.address_ && port_ == that.port_;
117}
118
119} // namespace net