16316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum/*
26316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * Copyright (C) 2015 The Android Open Source Project
36316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum *
46316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * Licensed under the Apache License, Version 2.0 (the "License");
56316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * you may not use this file except in compliance with the License.
66316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * You may obtain a copy of the License at
76316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum *
86316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum *      http://www.apache.org/licenses/LICENSE-2.0
96316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum *
106316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * Unless required by applicable law or agreed to in writing, software
116316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * distributed under the License is distributed on an "AS IS" BASIS,
126316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * See the License for the specific language governing permissions and
146316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum * limitations under the License.
156316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum */
166316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
176316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#define LOG_TAG "IpPrefix"
186316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
196316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#include <binder/IpPrefix.h>
206316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#include <vector>
216316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
226316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#include <binder/IBinder.h>
236316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#include <binder/Parcel.h>
246316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#include <log/log.h>
256316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#include <utils/Errors.h>
266316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
276316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumusing android::BAD_TYPE;
286316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumusing android::BAD_VALUE;
296316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumusing android::NO_ERROR;
306316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumusing android::Parcel;
316316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumusing android::status_t;
326316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumusing android::UNEXPECTED_NULL;
336316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumusing namespace ::android::binder;
346316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
356316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumnamespace android {
366316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
376316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumnamespace net {
386316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
396316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum#define RETURN_IF_FAILED(calledOnce)                                     \
406316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    {                                                                    \
416316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        status_t returnStatus = calledOnce;                              \
426316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        if (returnStatus) {                                              \
436316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
446316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum            return returnStatus;                                         \
456316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum         }                                                               \
466316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
476316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
486316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumstatus_t IpPrefix::writeToParcel(Parcel* parcel) const {
496316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    /*
506316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum     * Keep implementation in sync with writeToParcel() in
516316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum     * frameworks/base/core/java/android/net/IpPrefix.java.
526316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum     */
536316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    std::vector<uint8_t> byte_vector;
546316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
556316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    if (mIsIpv6) {
566316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mIn6Addr);
576316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
586316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    } else {
596316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mInAddr);
606316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
616316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
626316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
636316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    RETURN_IF_FAILED(parcel->writeByteVector(byte_vector));
646316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(mPrefixLength)));
656316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
666316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return NO_ERROR;
676316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
686316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
696316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumstatus_t IpPrefix::readFromParcel(const Parcel* parcel) {
706316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    /*
716316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum     * Keep implementation in sync with readFromParcel() in
726316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum     * frameworks/base/core/java/android/net/IpPrefix.java.
736316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum     */
746316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    std::vector<uint8_t> byte_vector;
756316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
766316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    RETURN_IF_FAILED(parcel->readByteVector(&byte_vector));
776316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    RETURN_IF_FAILED(parcel->readInt32(&mPrefixLength));
786316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
796316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    if (byte_vector.size() == 16) {
806316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        mIsIpv6 = true;
816316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        memcpy((void*)&mUnion.mIn6Addr, &byte_vector[0], sizeof(mUnion.mIn6Addr));
826316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
836316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    } else if (byte_vector.size() == 4) {
846316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        mIsIpv6 = false;
856316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        memcpy((void*)&mUnion.mInAddr, &byte_vector[0], sizeof(mUnion.mInAddr));
866316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
876316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    } else {
886316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
896316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        return BAD_VALUE;
906316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
916316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
926316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return NO_ERROR;
936316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
946316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
956316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumconst struct in6_addr& IpPrefix::getAddressAsIn6Addr() const
966316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
976316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return mUnion.mIn6Addr;
986316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
996316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1006316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumconst struct in_addr& IpPrefix::getAddressAsInAddr() const
1016316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1026316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return mUnion.mInAddr;
1036316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1046316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1056316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumbool IpPrefix::getAddressAsIn6Addr(struct in6_addr* addr) const
1066316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1076316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    if (isIpv6()) {
1086316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        *addr = mUnion.mIn6Addr;
1096316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        return true;
1106316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
1116316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return false;
1126316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1136316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1146316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumbool IpPrefix::getAddressAsInAddr(struct in_addr* addr) const
1156316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1166316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    if (isIpv4()) {
1176316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        *addr = mUnion.mInAddr;
1186316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        return true;
1196316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
1206316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return false;
1216316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1226316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1236316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumbool IpPrefix::isIpv6() const
1246316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1256316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return mIsIpv6;
1266316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1276316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1286316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumbool IpPrefix::isIpv4() const
1296316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1306316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return !mIsIpv6;
1316316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1326316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1336316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumint32_t IpPrefix::getPrefixLength() const
1346316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1356316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return mPrefixLength;
1366316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1376316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1386316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumvoid IpPrefix::setAddress(const struct in6_addr& addr)
1396316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1406316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    mUnion.mIn6Addr = addr;
1416316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    mIsIpv6 = true;
1426316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1436316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1446316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumvoid IpPrefix::setAddress(const struct in_addr& addr)
1456316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1466316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    mUnion.mInAddr = addr;
1476316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    mIsIpv6 = false;
1486316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1496316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1506316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumvoid IpPrefix::setPrefixLength(int32_t prefix)
1516316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1526316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    mPrefixLength = prefix;
1536316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1546316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1556316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaumbool operator==(const IpPrefix& lhs, const IpPrefix& rhs)
1566316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum{
1576316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    if (lhs.mIsIpv6 != rhs.mIsIpv6) {
1586316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        return false;
1596316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
1606316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1616316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    if (lhs.mPrefixLength != rhs.mPrefixLength) {
1626316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        return false;
1636316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
1646316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1656316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    if (lhs.mIsIpv6) {
1666316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum        return 0 == memcmp(lhs.mUnion.mIn6Addr.s6_addr, rhs.mUnion.mIn6Addr.s6_addr, sizeof(struct in6_addr));
1676316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    }
1686316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1696316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum    return 0 == memcmp(&lhs.mUnion.mInAddr, &rhs.mUnion.mInAddr, sizeof(struct in_addr));
1706316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}
1716316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1726316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}  // namespace net
1736316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum
1746316f5b8df30422b247c2bfd1a805dcd4069b54eRobert Quattlebaum}  // namespace android
175