Home | History | Annotate | Download | only in binder
      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
    175