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