• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
writeToParcel(Parcel * parcel) const47 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 
readFromParcel(const Parcel * parcel)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 
getAddressAsIn6Addr() const94 const struct in6_addr& IpPrefix::getAddressAsIn6Addr() const
95 {
96     return mUnion.mIn6Addr;
97 }
98 
getAddressAsInAddr() const99 const struct in_addr& IpPrefix::getAddressAsInAddr() const
100 {
101     return mUnion.mInAddr;
102 }
103 
getAddressAsIn6Addr(struct in6_addr * addr) const104 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 
getAddressAsInAddr(struct in_addr * addr) const113 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 
isIpv6() const122 bool IpPrefix::isIpv6() const
123 {
124     return mIsIpv6;
125 }
126 
isIpv4() const127 bool IpPrefix::isIpv4() const
128 {
129     return !mIsIpv6;
130 }
131 
getPrefixLength() const132 int32_t IpPrefix::getPrefixLength() const
133 {
134     return mPrefixLength;
135 }
136 
setAddress(const struct in6_addr & addr)137 void IpPrefix::setAddress(const struct in6_addr& addr)
138 {
139     mUnion.mIn6Addr = addr;
140     mIsIpv6 = true;
141 }
142 
setAddress(const struct in_addr & addr)143 void IpPrefix::setAddress(const struct in_addr& addr)
144 {
145     mUnion.mInAddr = addr;
146     mIsIpv6 = false;
147 }
148 
setPrefixLength(int32_t prefix)149 void IpPrefix::setPrefixLength(int32_t prefix)
150 {
151     mPrefixLength = prefix;
152 }
153 
operator ==(const IpPrefix & lhs,const IpPrefix & rhs)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
174