blob: 4edc493f1174a3fa9d1d37fc3fad46f4093b71aa [file] [log] [blame]
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "IpPrefix"
18
19#include <binder/IpPrefix.h>
20#include <vector>
21
22#include <binder/IBinder.h>
23#include <binder/Parcel.h>
24#include <log/log.h>
25#include <utils/Errors.h>
26
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -080027using android::BAD_VALUE;
28using android::NO_ERROR;
29using android::Parcel;
30using android::status_t;
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -080031
32namespace android {
33
34namespace net {
35
36#define RETURN_IF_FAILED(calledOnce) \
37 { \
38 status_t returnStatus = calledOnce; \
39 if (returnStatus) { \
40 ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
41 return returnStatus; \
42 } \
43 }
44
45status_t IpPrefix::writeToParcel(Parcel* parcel) const {
46 /*
47 * Keep implementation in sync with writeToParcel() in
48 * frameworks/base/core/java/android/net/IpPrefix.java.
49 */
50 std::vector<uint8_t> byte_vector;
51
52 if (mIsIpv6) {
53 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mIn6Addr);
54 byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
55 } else {
56 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mInAddr);
57 byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
58 }
59
60 RETURN_IF_FAILED(parcel->writeByteVector(byte_vector));
61 RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(mPrefixLength)));
62
63 return NO_ERROR;
64}
65
66status_t IpPrefix::readFromParcel(const Parcel* parcel) {
67 /*
68 * Keep implementation in sync with readFromParcel() in
69 * frameworks/base/core/java/android/net/IpPrefix.java.
70 */
71 std::vector<uint8_t> byte_vector;
72
73 RETURN_IF_FAILED(parcel->readByteVector(&byte_vector));
74 RETURN_IF_FAILED(parcel->readInt32(&mPrefixLength));
75
76 if (byte_vector.size() == 16) {
77 mIsIpv6 = true;
78 memcpy((void*)&mUnion.mIn6Addr, &byte_vector[0], sizeof(mUnion.mIn6Addr));
79
80 } else if (byte_vector.size() == 4) {
81 mIsIpv6 = false;
82 memcpy((void*)&mUnion.mInAddr, &byte_vector[0], sizeof(mUnion.mInAddr));
83
84 } else {
85 ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
86 return BAD_VALUE;
87 }
88
89 return NO_ERROR;
90}
91
92const struct in6_addr& IpPrefix::getAddressAsIn6Addr() const
93{
94 return mUnion.mIn6Addr;
95}
96
97const struct in_addr& IpPrefix::getAddressAsInAddr() const
98{
99 return mUnion.mInAddr;
100}
101
102bool IpPrefix::getAddressAsIn6Addr(struct in6_addr* addr) const
103{
104 if (isIpv6()) {
105 *addr = mUnion.mIn6Addr;
106 return true;
107 }
108 return false;
109}
110
111bool IpPrefix::getAddressAsInAddr(struct in_addr* addr) const
112{
113 if (isIpv4()) {
114 *addr = mUnion.mInAddr;
115 return true;
116 }
117 return false;
118}
119
120bool IpPrefix::isIpv6() const
121{
122 return mIsIpv6;
123}
124
125bool IpPrefix::isIpv4() const
126{
127 return !mIsIpv6;
128}
129
130int32_t IpPrefix::getPrefixLength() const
131{
132 return mPrefixLength;
133}
134
135void IpPrefix::setAddress(const struct in6_addr& addr)
136{
137 mUnion.mIn6Addr = addr;
138 mIsIpv6 = true;
139}
140
141void IpPrefix::setAddress(const struct in_addr& addr)
142{
143 mUnion.mInAddr = addr;
144 mIsIpv6 = false;
145}
146
147void IpPrefix::setPrefixLength(int32_t prefix)
148{
149 mPrefixLength = prefix;
150}
151
152bool operator==(const IpPrefix& lhs, const IpPrefix& rhs)
153{
154 if (lhs.mIsIpv6 != rhs.mIsIpv6) {
155 return false;
156 }
157
158 if (lhs.mPrefixLength != rhs.mPrefixLength) {
159 return false;
160 }
161
162 if (lhs.mIsIpv6) {
163 return 0 == memcmp(lhs.mUnion.mIn6Addr.s6_addr, rhs.mUnion.mIn6Addr.s6_addr, sizeof(struct in6_addr));
164 }
165
166 return 0 == memcmp(&lhs.mUnion.mInAddr, &rhs.mUnion.mInAddr, sizeof(struct in_addr));
167}
168
169} // namespace net
170
171} // namespace android