| Robert Quattlebaum | 6316f5b | 2017-01-04 13:25:14 -0800 | [diff] [blame] | 1 | /* | 
|  | 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 |  | 
|  | 27 | using android::BAD_TYPE; | 
|  | 28 | using android::BAD_VALUE; | 
|  | 29 | using android::NO_ERROR; | 
|  | 30 | using android::Parcel; | 
|  | 31 | using android::status_t; | 
|  | 32 | using android::UNEXPECTED_NULL; | 
| Robert Quattlebaum | 6316f5b | 2017-01-04 13:25:14 -0800 | [diff] [blame] | 33 |  | 
|  | 34 | namespace android { | 
|  | 35 |  | 
|  | 36 | namespace net { | 
|  | 37 |  | 
|  | 38 | #define RETURN_IF_FAILED(calledOnce)                                     \ | 
|  | 39 | {                                                                    \ | 
|  | 40 | status_t returnStatus = calledOnce;                              \ | 
|  | 41 | if (returnStatus) {                                              \ | 
|  | 42 | ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ | 
|  | 43 | return returnStatus;                                         \ | 
|  | 44 | }                                                               \ | 
|  | 45 | } | 
|  | 46 |  | 
|  | 47 | status_t IpPrefix::writeToParcel(Parcel* parcel) const { | 
|  | 48 | /* | 
|  | 49 | * Keep implementation in sync with writeToParcel() in | 
|  | 50 | * frameworks/base/core/java/android/net/IpPrefix.java. | 
|  | 51 | */ | 
|  | 52 | std::vector<uint8_t> byte_vector; | 
|  | 53 |  | 
|  | 54 | if (mIsIpv6) { | 
|  | 55 | const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mIn6Addr); | 
|  | 56 | byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr)); | 
|  | 57 | } else { | 
|  | 58 | const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mInAddr); | 
|  | 59 | byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr)); | 
|  | 60 | } | 
|  | 61 |  | 
|  | 62 | RETURN_IF_FAILED(parcel->writeByteVector(byte_vector)); | 
|  | 63 | RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(mPrefixLength))); | 
|  | 64 |  | 
|  | 65 | return NO_ERROR; | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | status_t IpPrefix::readFromParcel(const Parcel* parcel) { | 
|  | 69 | /* | 
|  | 70 | * Keep implementation in sync with readFromParcel() in | 
|  | 71 | * frameworks/base/core/java/android/net/IpPrefix.java. | 
|  | 72 | */ | 
|  | 73 | std::vector<uint8_t> byte_vector; | 
|  | 74 |  | 
|  | 75 | RETURN_IF_FAILED(parcel->readByteVector(&byte_vector)); | 
|  | 76 | RETURN_IF_FAILED(parcel->readInt32(&mPrefixLength)); | 
|  | 77 |  | 
|  | 78 | if (byte_vector.size() == 16) { | 
|  | 79 | mIsIpv6 = true; | 
|  | 80 | memcpy((void*)&mUnion.mIn6Addr, &byte_vector[0], sizeof(mUnion.mIn6Addr)); | 
|  | 81 |  | 
|  | 82 | } else if (byte_vector.size() == 4) { | 
|  | 83 | mIsIpv6 = false; | 
|  | 84 | memcpy((void*)&mUnion.mInAddr, &byte_vector[0], sizeof(mUnion.mInAddr)); | 
|  | 85 |  | 
|  | 86 | } else { | 
|  | 87 | ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ | 
|  | 88 | return BAD_VALUE; | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | return NO_ERROR; | 
|  | 92 | } | 
|  | 93 |  | 
|  | 94 | const struct in6_addr& IpPrefix::getAddressAsIn6Addr() const | 
|  | 95 | { | 
|  | 96 | return mUnion.mIn6Addr; | 
|  | 97 | } | 
|  | 98 |  | 
|  | 99 | const struct in_addr& IpPrefix::getAddressAsInAddr() const | 
|  | 100 | { | 
|  | 101 | return mUnion.mInAddr; | 
|  | 102 | } | 
|  | 103 |  | 
|  | 104 | bool IpPrefix::getAddressAsIn6Addr(struct in6_addr* addr) const | 
|  | 105 | { | 
|  | 106 | if (isIpv6()) { | 
|  | 107 | *addr = mUnion.mIn6Addr; | 
|  | 108 | return true; | 
|  | 109 | } | 
|  | 110 | return false; | 
|  | 111 | } | 
|  | 112 |  | 
|  | 113 | bool IpPrefix::getAddressAsInAddr(struct in_addr* addr) const | 
|  | 114 | { | 
|  | 115 | if (isIpv4()) { | 
|  | 116 | *addr = mUnion.mInAddr; | 
|  | 117 | return true; | 
|  | 118 | } | 
|  | 119 | return false; | 
|  | 120 | } | 
|  | 121 |  | 
|  | 122 | bool IpPrefix::isIpv6() const | 
|  | 123 | { | 
|  | 124 | return mIsIpv6; | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | bool IpPrefix::isIpv4() const | 
|  | 128 | { | 
|  | 129 | return !mIsIpv6; | 
|  | 130 | } | 
|  | 131 |  | 
|  | 132 | int32_t IpPrefix::getPrefixLength() const | 
|  | 133 | { | 
|  | 134 | return mPrefixLength; | 
|  | 135 | } | 
|  | 136 |  | 
|  | 137 | void IpPrefix::setAddress(const struct in6_addr& addr) | 
|  | 138 | { | 
|  | 139 | mUnion.mIn6Addr = addr; | 
|  | 140 | mIsIpv6 = true; | 
|  | 141 | } | 
|  | 142 |  | 
|  | 143 | void IpPrefix::setAddress(const struct in_addr& addr) | 
|  | 144 | { | 
|  | 145 | mUnion.mInAddr = addr; | 
|  | 146 | mIsIpv6 = false; | 
|  | 147 | } | 
|  | 148 |  | 
|  | 149 | void IpPrefix::setPrefixLength(int32_t prefix) | 
|  | 150 | { | 
|  | 151 | mPrefixLength = prefix; | 
|  | 152 | } | 
|  | 153 |  | 
|  | 154 | bool operator==(const IpPrefix& lhs, const IpPrefix& rhs) | 
|  | 155 | { | 
|  | 156 | if (lhs.mIsIpv6 != rhs.mIsIpv6) { | 
|  | 157 | return false; | 
|  | 158 | } | 
|  | 159 |  | 
|  | 160 | if (lhs.mPrefixLength != rhs.mPrefixLength) { | 
|  | 161 | return false; | 
|  | 162 | } | 
|  | 163 |  | 
|  | 164 | if (lhs.mIsIpv6) { | 
|  | 165 | return 0 == memcmp(lhs.mUnion.mIn6Addr.s6_addr, rhs.mUnion.mIn6Addr.s6_addr, sizeof(struct in6_addr)); | 
|  | 166 | } | 
|  | 167 |  | 
|  | 168 | return 0 == memcmp(&lhs.mUnion.mInAddr, &rhs.mUnion.mInAddr, sizeof(struct in_addr)); | 
|  | 169 | } | 
|  | 170 |  | 
|  | 171 | }  // namespace net | 
|  | 172 |  | 
|  | 173 | }  // namespace android |