/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; import android.os.Parcel; import android.os.Parcelable; import android.util.Pair; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; /** * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of * information: * *
192.0.2.0/24
covers the 256 IPv4 addresses from
* 192.0.2.0
to 192.0.2.255
, inclusive, and the prefix
* 2001:db8:1:2
covers the 2^64 IPv6 addresses from 2001:db8:1:2::
to
* 2001:db8:1:2:ffff:ffff:ffff:ffff
, inclusive.
*
* Objects of this class are immutable.
*/
public final class IpPrefix implements Parcelable {
private final byte[] address; // network byte order
private final int prefixLength;
private void checkAndMaskAddressAndPrefixLength() {
if (address.length != 4 && address.length != 16) {
throw new IllegalArgumentException(
"IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
}
NetworkUtils.maskRawAddress(address, prefixLength);
}
/**
* Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
* network byte order and a prefix length. Silently truncates the address to the prefix length,
* so for example {@code 192.0.2.1/24} is silently converted to {@code 192.0.2.0/24}.
*
* @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
* @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
*
* @hide
*/
public IpPrefix(byte[] address, int prefixLength) {
this.address = address.clone();
this.prefixLength = prefixLength;
checkAndMaskAddressAndPrefixLength();
}
/**
* Constructs a new {@code IpPrefix} from an IPv4 or IPv6 address and a prefix length. Silently
* truncates the address to the prefix length, so for example {@code 192.0.2.1/24} is silently
* converted to {@code 192.0.2.0/24}.
*
* @param address the IP address. Must be non-null.
* @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
* @hide
*/
public IpPrefix(InetAddress address, int prefixLength) {
// We don't reuse the (byte[], int) constructor because it calls clone() on the byte array,
// which is unnecessary because getAddress() already returns a clone.
this.address = address.getAddress();
this.prefixLength = prefixLength;
checkAndMaskAddressAndPrefixLength();
}
/**
* Constructs a new IpPrefix from a string such as "192.0.2.1/24" or "2001:db8::1/64".
* Silently truncates the address to the prefix length, so for example {@code 192.0.2.1/24}
* is silently converted to {@code 192.0.2.0/24}.
*
* @param prefix the prefix to parse
*
* @hide
*/
public IpPrefix(String prefix) {
// We don't reuse the (InetAddress, int) constructor because "error: call to this must be
// first statement in constructor". We could factor out setting the member variables to an
// init() method, but if we did, then we'd have to make the members non-final, or "error:
// cannot assign a value to final variable address". So we just duplicate the code here.
Pair