1ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff/* 2ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Copyright (C) 2010 The Android Open Source Project 3ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 4ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License"); 5ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * you may not use this file except in compliance with the License. 6ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * You may obtain a copy of the License at 7ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 8ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * http://www.apache.org/licenses/LICENSE-2.0 9ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 10ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Unless required by applicable law or agreed to in writing, software 11ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS, 12ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * See the License for the specific language governing permissions and 14ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * limitations under the License. 15ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 16ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 17ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffpackage android.net; 18ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 19ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.os.Parcel; 20ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.os.Parcelable; 21ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 22b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwaltimport java.net.Inet4Address; 23ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.InetAddress; 24ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.InterfaceAddress; 25ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.UnknownHostException; 26ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 27ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff/** 28ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Identifies an address of a network link 29ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @hide 30ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 31ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffpublic class LinkAddress implements Parcelable { 32ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 33ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * IPv4 or IPv6 address. 34ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 356eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti private InetAddress address; 36ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 37ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 3896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff * Network prefix length 39ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 406eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti private int prefixLength; 41ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 426eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti private void init(InetAddress address, int prefixLength) { 43b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt if (address == null || prefixLength < 0 || 44b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt ((address instanceof Inet4Address) && prefixLength > 32) || 45b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt (prefixLength > 128)) { 46b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt throw new IllegalArgumentException("Bad LinkAddress params " + address + 476eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti "/" + prefixLength); 48b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt } 49ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff this.address = address; 5096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff this.prefixLength = prefixLength; 51ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 52ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 536eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti public LinkAddress(InetAddress address, int prefixLength) { 546eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti init(address, prefixLength); 556eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 566eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 57ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress(InterfaceAddress interfaceAddress) { 586eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti init(interfaceAddress.getAddress(), 596eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti interfaceAddress.getNetworkPrefixLength()); 606eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 616eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 626eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti /** 636eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or 646eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti * "2001:db8::1/64". 656eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti * @param string The string to parse. 666eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti */ 676eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti public LinkAddress(String address) { 686eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti InetAddress inetAddress = null; 696eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti int prefixLength = -1; 706eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti try { 716eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti String [] pieces = address.split("/", 2); 726eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti prefixLength = Integer.parseInt(pieces[1]); 736eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti inetAddress = InetAddress.parseNumericAddress(pieces[0]); 746eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } catch (NullPointerException e) { // Null string. 756eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } catch (ArrayIndexOutOfBoundsException e) { // No prefix length. 766eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } catch (NumberFormatException e) { // Non-numeric prefix. 776eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } catch (IllegalArgumentException e) { // Invalid IP address. 786eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 796eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 806eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti if (inetAddress == null || prefixLength == -1) { 816eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti throw new IllegalArgumentException("Bad LinkAddress params " + address); 826eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 836eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 846eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti init(inetAddress, prefixLength); 85ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 86ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 87ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff @Override 88ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public String toString() { 8996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff return (address == null ? "" : (address.getHostAddress() + "/" + prefixLength)); 90ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 91ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 92ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 93ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Compares this {@code LinkAddress} instance against the specified address 9496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff * in {@code obj}. Two addresses are equal if their InetAddress and prefixLength 95ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * are equal 96ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 97ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @param obj the object to be tested for equality. 98ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @return {@code true} if both objects are equal, {@code false} otherwise. 99ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 100ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff @Override 101ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public boolean equals(Object obj) { 102ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff if (!(obj instanceof LinkAddress)) { 103ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return false; 104ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 105ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff LinkAddress linkAddress = (LinkAddress) obj; 106ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return this.address.equals(linkAddress.address) && 10796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff this.prefixLength == linkAddress.prefixLength; 108ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 109ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 1104e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang @Override 1114e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang /* 1124e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang * generate hashcode based on significant fields 1134e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang */ 1144e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang public int hashCode() { 1154e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang return ((null == address) ? 0 : address.hashCode()) + prefixLength; 1164e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang } 1174e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang 118ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 119ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Returns the InetAddress for this address. 120ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 121ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public InetAddress getAddress() { 122ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return address; 123ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 124ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 125ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 126ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Get network prefix length 127ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 12896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff public int getNetworkPrefixLength() { 12996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff return prefixLength; 130ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 131ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 132ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 133ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Implement the Parcelable interface 134ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @hide 135ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 136ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public int describeContents() { 137ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return 0; 138ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 139ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 140ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 141ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Implement the Parcelable interface. 142ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @hide 143ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 144ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public void writeToParcel(Parcel dest, int flags) { 145ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff if (address != null) { 146ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff dest.writeByte((byte)1); 147ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff dest.writeByteArray(address.getAddress()); 14896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff dest.writeInt(prefixLength); 149ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } else { 150ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff dest.writeByte((byte)0); 151ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 152ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 153ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 154ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 155ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Implement the Parcelable interface. 156ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @hide 157ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 158ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public static final Creator<LinkAddress> CREATOR = 159ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff new Creator<LinkAddress>() { 160ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress createFromParcel(Parcel in) { 161ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff InetAddress address = null; 16296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff int prefixLength = 0; 163ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff if (in.readByte() == 1) { 164ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff try { 165ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff address = InetAddress.getByAddress(in.createByteArray()); 16696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff prefixLength = in.readInt(); 167ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } catch (UnknownHostException e) { } 168ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 16996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff return new LinkAddress(address, prefixLength); 170ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 171ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 172ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress[] newArray(int size) { 173ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return new LinkAddress[size]; 174ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 175ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff }; 176ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff} 177