1cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran/*
2cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Copyright (C) 2014 The Android Open Source Project
3cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *
4cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Licensed under the Apache License, Version 2.0 (the "License");
5cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * you may not use this file except in compliance with the License.
6cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * You may obtain a copy of the License at
7cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *
8cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *      http://www.apache.org/licenses/LICENSE-2.0
9cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *
10cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Unless required by applicable law or agreed to in writing, software
11cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * distributed under the License is distributed on an "AS IS" BASIS,
12cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * See the License for the specific language governing permissions and
14cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * limitations under the License.
15cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */
16cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
17cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandranpackage android.net;
18cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
19cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandranimport android.os.Parcel;
20cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandranimport android.os.Parcelable;
218c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colittiimport android.util.Pair;
22cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
23cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandranimport java.net.InetAddress;
24cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandranimport java.net.UnknownHostException;
25cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandranimport java.util.Arrays;
26cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
27cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran/**
28cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a
29cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of
30cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * information:
31cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *
32cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <ul>
33cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix.
34cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <li>A prefix length. This specifies the length of the prefix by specifing the number of bits
35cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *     in the IP address, starting from the most significant bit in network byte order, that
36cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *     are constant for all addresses in the prefix.
37cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * </ul>
38cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *
39cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from
40cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix
41cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <code>2001:db8:1:2</code>  covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to
42cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive.
43cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran *
44cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Objects of this class are immutable.
45cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */
460cbe94a349616442672fad3751ac81f4f7f394f3Robert Greenwaltpublic final class IpPrefix implements Parcelable {
47cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    private final byte[] address;  // network byte order
48cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    private final int prefixLength;
49cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
508c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    private void checkAndMaskAddressAndPrefixLength() {
518c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        if (address.length != 4 && address.length != 16) {
528c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            throw new IllegalArgumentException(
538c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti                    "IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
548c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        }
558c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        NetworkUtils.maskRawAddress(address, prefixLength);
568c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    }
578c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
58cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
59cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
608c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * network byte order and a prefix length. Silently truncates the address to the prefix length,
618c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * so for example {@code 192.0.2.1/24} is silently converted to {@code 192.0.2.0/24}.
62cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     *
63cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
64cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @param prefixLength the prefix length. Must be &gt;= 0 and &lt;= (32 or 128) (IPv4 or IPv6).
65cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     *
66cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @hide
67cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
68cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public IpPrefix(byte[] address, int prefixLength) {
69cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        this.address = address.clone();
70cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        this.prefixLength = prefixLength;
718c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        checkAndMaskAddressAndPrefixLength();
72cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
73cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
74cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
758c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Constructs a new {@code IpPrefix} from an IPv4 or IPv6 address and a prefix length. Silently
768c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * truncates the address to the prefix length, so for example {@code 192.0.2.1/24} is silently
778c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * converted to {@code 192.0.2.0/24}.
788c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     *
798c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @param address the IP address. Must be non-null.
808c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @param prefixLength the prefix length. Must be &gt;= 0 and &lt;= (32 or 128) (IPv4 or IPv6).
81cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @hide
82cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
83cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public IpPrefix(InetAddress address, int prefixLength) {
848c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        // We don't reuse the (byte[], int) constructor because it calls clone() on the byte array,
858c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        // which is unnecessary because getAddress() already returns a clone.
868c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        this.address = address.getAddress();
878c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        this.prefixLength = prefixLength;
888c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        checkAndMaskAddressAndPrefixLength();
898c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    }
908c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
918c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    /**
928c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Constructs a new IpPrefix from a string such as "192.0.2.1/24" or "2001:db8::1/64".
938c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Silently truncates the address to the prefix length, so for example {@code 192.0.2.1/24}
948c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * is silently converted to {@code 192.0.2.0/24}.
958c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     *
968c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @param prefix the prefix to parse
978c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     *
988c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @hide
998c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     */
1008c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public IpPrefix(String prefix) {
1018c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        // We don't reuse the (InetAddress, int) constructor because "error: call to this must be
1028c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        // first statement in constructor". We could factor out setting the member variables to an
1038c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        // init() method, but if we did, then we'd have to make the members non-final, or "error:
1048c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        // cannot assign a value to final variable address". So we just duplicate the code here.
1058c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(prefix);
1068c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        this.address = ipAndMask.first.getAddress();
1078c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        this.prefixLength = ipAndMask.second;
1088c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        checkAndMaskAddressAndPrefixLength();
109cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
110cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
111cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
112cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Compares this {@code IpPrefix} object against the specified object in {@code obj}. Two
113cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * objects are equal if they have the same startAddress and prefixLength.
114cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     *
115cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @param obj the object to be tested for equality.
116cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @return {@code true} if both objects are equal, {@code false} otherwise.
117cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
118cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    @Override
119cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public boolean equals(Object obj) {
120cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        if (!(obj instanceof IpPrefix)) {
121cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran            return false;
122cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        }
123cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        IpPrefix that = (IpPrefix) obj;
124cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        return Arrays.equals(this.address, that.address) && this.prefixLength == that.prefixLength;
125cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
126cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
127cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
128cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Gets the hashcode of the represented IP prefix.
129cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     *
130cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @return the appropriate hashcode value.
131cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
132cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    @Override
133cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public int hashCode() {
134cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        return Arrays.hashCode(address) + 11 * prefixLength;
135cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
136cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
137cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
138cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Returns a copy of the first IP address in the prefix. Modifying the returned object does not
139cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * change this object's contents.
140cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     *
141cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @return the address in the form of a byte array.
142cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
143cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public InetAddress getAddress() {
144cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        try {
145cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran            return InetAddress.getByAddress(address);
146cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        } catch (UnknownHostException e) {
147cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran            // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
148cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran            // array is the wrong length, but we check that in the constructor.
149cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran            return null;
150cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        }
151cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
152cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
153cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
154cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Returns a copy of the IP address bytes in network order (the highest order byte is the zeroth
155cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * element). Modifying the returned array does not change this object's contents.
156cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     *
157cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @return the address in the form of a byte array.
158cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
159cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public byte[] getRawAddress() {
160cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        return address.clone();
161cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
162cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
163cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
1648c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Returns the prefix length of this {@code IpPrefix}.
165cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     *
166cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @return the prefix length.
167cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
168cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public int getPrefixLength() {
169cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        return prefixLength;
170cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
171cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
172cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
173acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline     * Determines whether the prefix contains the specified address.
174acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline     *
175acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline     * @param address An {@link InetAddress} to test.
176acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline     * @return {@code true} if the prefix covers the given address.
177acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline     */
178acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline    public boolean contains(InetAddress address) {
179acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline        byte[] addrBytes = (address == null) ? null : address.getAddress();
180acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline        if (addrBytes == null || addrBytes.length != this.address.length) {
181acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline            return false;
182acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline        }
183acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline        NetworkUtils.maskRawAddress(addrBytes, prefixLength);
184acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline        return Arrays.equals(this.address, addrBytes);
185acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline    }
186acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline
187acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline    /**
1888c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Returns a string representation of this {@code IpPrefix}.
1898c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     *
1904b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti     * @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}.
1918c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     */
1928c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public String toString() {
1938c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        try {
1948c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            return InetAddress.getByAddress(address).getHostAddress() + "/" + prefixLength;
1958c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch(UnknownHostException e) {
1968c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            // Cosmic rays?
1978c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            throw new IllegalStateException("IpPrefix with invalid address! Shouldn't happen.", e);
1988c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        }
1998c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    }
2008c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2018c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    /**
202cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Implement the Parcelable interface.
203cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
204cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public int describeContents() {
205cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        return 0;
206cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
207cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
208cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
209cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Implement the Parcelable interface.
210cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
211cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public void writeToParcel(Parcel dest, int flags) {
212cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        dest.writeByteArray(address);
213cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        dest.writeInt(prefixLength);
214cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    }
215cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
216cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
217cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Implement the Parcelable interface.
218cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
219cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    public static final Creator<IpPrefix> CREATOR =
220cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran            new Creator<IpPrefix>() {
221cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                public IpPrefix createFromParcel(Parcel in) {
222cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                    byte[] address = in.createByteArray();
223cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                    int prefixLength = in.readInt();
224cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                    return new IpPrefix(address, prefixLength);
225cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                }
226cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran
227cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                public IpPrefix[] newArray(int size) {
228cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                    return new IpPrefix[size];
229cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran                }
230cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran            };
231cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran}
232