RouteInfo.java revision 1806b1fc25bcffaa005e72a55042031a42b168b1
1aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt/* 2aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * Copyright (C) 2011 The Android Open Source Project 3aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * 4aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 5aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * you may not use this file except in compliance with the License. 6aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * You may obtain a copy of the License at 7aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * 8aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 9aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * 10aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * Unless required by applicable law or agreed to in writing, software 11aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 12aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * See the License for the specific language governing permissions and 14aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * limitations under the License. 15aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt */ 16aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 17aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltpackage android.net; 18aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 19aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport android.os.Parcel; 20aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport android.os.Parcelable; 21aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 22aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport java.net.UnknownHostException; 23aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport java.net.InetAddress; 24aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport java.net.Inet4Address; 25aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport java.net.Inet6Address; 26f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt 27f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwaltimport java.util.Collection; 28386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwaltimport java.util.Objects; 29f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt 30aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt/** 31386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * Represents a network route. 324095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * <p> 334095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * This is used both to describe static network configuration and live network 34386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * configuration information. 35aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * 36386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * A route contains three pieces of information: 374095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * <ul> 38cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route. 39cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6) 40386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * implied by the gateway IP address. 41cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * <li>a gateway {@link InetAddress} indicating the next hop to use. If this is {@code null} it 42386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * indicates a directly-connected route. 43386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * <li>an interface (which may be unspecified). 444095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * </ul> 45386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * Either the destination or the gateway may be {@code null}, but not both. If the 46386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * destination and gateway are both specified, they must be of the same address family 47386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * (IPv4 or IPv6). 48aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt */ 49e595b97ff470a5e92151350e4d7b4173032fde23Robert Greenwaltpublic final class RouteInfo implements Parcelable { 50aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt /** 51aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * The IP destination address for this route. 52aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt */ 531806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti private final IpPrefix mDestination; 54aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 55aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt /** 56aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * The gateway address for this route. 57aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt */ 58aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt private final InetAddress mGateway; 59aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 6045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti /** 6145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * The interface for this route. 6245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti */ 6345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti private final String mInterface; 6445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 650a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt private final boolean mIsHost; 66ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt private final boolean mHasGateway; 67aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 6845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti /** 6945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * Constructs a RouteInfo object. 7045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * 71574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti * If destination is null, then gateway must be specified and the 7245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * constructed route is either the IPv4 default route <code>0.0.0.0</code> 734095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default 74574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti * route <code>::/0</code> if gateway is an instance of 7545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * {@link Inet6Address}. 76386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * <p> 77574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti * destination and gateway may not both be null. 7845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * 7945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * @param destination the destination prefix 8045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * @param gateway the IP address to route packets through 8145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * @param iface the interface name to send packets on 82cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 83cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 84cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 85cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) { 86aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt if (destination == null) { 8759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (gateway != null) { 8859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (gateway instanceof Inet4Address) { 891806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti destination = new IpPrefix(Inet4Address.ANY, 0); 90aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } else { 911806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti destination = new IpPrefix(Inet6Address.ANY, 0); 92aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 9359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } else { 9459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt // no destination, no gateway. invalid. 9545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," + 9645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti destination); 9759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 98aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 991806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti // TODO: set mGateway to null if there is no gateway. This is more correct, saves space, and 1001806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti // matches the documented behaviour. Before we can do this we need to fix all callers (e.g., 1011806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti // ConnectivityService) to stop doing things like r.getGateway().equals(), ... . 1028c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo if (gateway == null) { 1038c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo if (destination.getAddress() instanceof Inet4Address) { 1048c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo gateway = Inet4Address.ANY; 1058c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo } else { 1068c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo gateway = Inet6Address.ANY; 1078c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo } 1088c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo } 109ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt mHasGateway = (!gateway.isAnyLocalAddress()); 110ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt 111386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt if ((destination.getAddress() instanceof Inet4Address && 112386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt (gateway instanceof Inet4Address == false)) || 113386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt (destination.getAddress() instanceof Inet6Address && 114386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt (gateway instanceof Inet6Address == false))) { 115386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt throw new IllegalArgumentException("address family mismatch in RouteInfo constructor"); 116386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt } 1171806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti mDestination = destination; // IpPrefix objects are immutable. 1181806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti mGateway = gateway; // InetAddress objects are immutable. 1191806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti mInterface = iface; // Strings are immutable. 1200a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt mIsHost = isHost(); 121aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 122aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 1234095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 1241806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti * @hide 1251806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti */ 1261806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { 1271806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti this(destination == null ? null : 1281806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti new IpPrefix(destination.getAddress(), destination.getPrefixLength()), 1291806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti gateway, iface); 1301806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti } 1311806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti 1321806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti /** 1334095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Constructs a {@code RouteInfo} object. 1344095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 1354095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * If destination is null, then gateway must be specified and the 1364095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * constructed route is either the IPv4 default route <code>0.0.0.0</code> 1374095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default 1384095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}. 1394095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * <p> 1404095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Destination and gateway may not both be null. 1414095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 142cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @param destination the destination address and prefix in an {@link IpPrefix} 1434095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param gateway the {@link InetAddress} to route packets through 144cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 145cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 146cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 147cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public RouteInfo(IpPrefix destination, InetAddress gateway) { 148cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran this(destination, gateway, null); 149cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran } 150cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran 151cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 152cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 1534095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 15445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti public RouteInfo(LinkAddress destination, InetAddress gateway) { 15545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti this(destination, gateway, null); 15645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti } 15745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 1584095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 1594095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Constructs a default {@code RouteInfo} object. 1604095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 1614095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param gateway the {@link InetAddress} to route packets through 162cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 163cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 1644095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 165aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public RouteInfo(InetAddress gateway) { 1661806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti this((IpPrefix) null, gateway, null); 167aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 168aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 1694095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 1704095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Constructs a {@code RouteInfo} object representing a direct connected subnet. 1714095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 172cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @param destination the {@link IpPrefix} describing the address and prefix 173386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * length of the subnet. 174cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 175cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 176cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 177cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public RouteInfo(IpPrefix destination) { 178cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran this(destination, null, null); 179cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran } 180cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran 181cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 182cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 1834095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 184386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt public RouteInfo(LinkAddress destination) { 185386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt this(destination, null, null); 1864717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt } 1874717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt 1884095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 1894095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @hide 1904095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 191e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti public static RouteInfo makeHostRoute(InetAddress host, String iface) { 192e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti return makeHostRoute(host, null, iface); 19359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 19459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt 1954095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 1964095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @hide 1974095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 198e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) { 19959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (host == null) return null; 20059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt 20159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (host instanceof Inet4Address) { 2021806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return new RouteInfo(new IpPrefix(host, 32), gateway, iface); 20359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } else { 2041806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return new RouteInfo(new IpPrefix(host, 128), gateway, iface); 20559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 20659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 20759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt 2080a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt private boolean isHost() { 209fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti return (mDestination.getAddress() instanceof Inet4Address && 2107dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti mDestination.getPrefixLength() == 32) || 211fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti (mDestination.getAddress() instanceof Inet6Address && 2127dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti mDestination.getPrefixLength() == 128); 2130a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt } 2140a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt 2154095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 216cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}. 2174095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 218cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @return {@link IpPrefix} specifying the destination. This is never {@code null}. 219cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 220cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public IpPrefix getDestination() { 2211806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return mDestination; 222cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran } 223cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran 224cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 225cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * TODO: Convert callers to use IpPrefix and then remove. 226cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 2274095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 228cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public LinkAddress getDestinationLinkAddress() { 2291806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength()); 230aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 231aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 2324095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2334095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Retrieves the gateway or next hop {@link InetAddress} for this route. 2344095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 235386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @return {@link InetAddress} specifying the gateway or next hop. This may be 236e595b97ff470a5e92151350e4d7b4173032fde23Robert Greenwalt * {@code null} for a directly-connected route." 2374095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 238aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public InetAddress getGateway() { 239aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt return mGateway; 240aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 241aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 2424095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 243386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * Retrieves the interface used for this route if specified, else {@code null}. 2444095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 2454095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @return The name of the interface used for this route. 2464095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 24745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti public String getInterface() { 24845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti return mInterface; 24945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti } 25045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 2514095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2524095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Indicates if this route is a default route (ie, has no destination specified). 2534095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 254386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @return {@code true} if the destination has a prefix length of 0. 2554095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 256aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public boolean isDefaultRoute() { 25764c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti return mDestination.getPrefixLength() == 0; 25864c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti } 25964c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti 26064c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti /** 26164c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * Indicates if this route is an IPv4 default route. 26264c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * @hide 26364c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti */ 26464c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti public boolean isIPv4Default() { 26564c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti return isDefaultRoute() && mDestination.getAddress() instanceof Inet4Address; 26664c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti } 26764c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti 26864c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti /** 26964c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * Indicates if this route is an IPv6 default route. 27064c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * @hide 27164c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti */ 27264c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti public boolean isIPv6Default() { 27364c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti return isDefaultRoute() && mDestination.getAddress() instanceof Inet6Address; 274aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 275aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 2764095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2774095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Indicates if this route is a host route (ie, matches only a single host address). 2784095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 279cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6, 280cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * respectively. 281386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @hide 2824095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 2830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt public boolean isHostRoute() { 2840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt return mIsHost; 2850a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt } 2860a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt 2874095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2884095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Indicates if this route has a next hop ({@code true}) or is directly-connected 2894095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * ({@code false}). 2904095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 2914095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @return {@code true} if a gateway is specified 292386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @hide 2934095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 294ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt public boolean hasGateway() { 295ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt return mHasGateway; 296ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt } 297ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt 2984095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 299386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * Determines whether the destination and prefix of this route includes the specified 300386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * address. 301386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * 302386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @param destination A {@link InetAddress} to test to see if it would match this route. 303386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @return {@code true} if the destination and prefix length cover the given address. 3044095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 305386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt public boolean matches(InetAddress destination) { 3064095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if (destination == null) return false; 307aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 3084095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt // match the route destination and destination with prefix length 3094095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt InetAddress dstNet = NetworkUtils.getNetworkPart(destination, 3107dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti mDestination.getPrefixLength()); 3114095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt 3124095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt return mDestination.getAddress().equals(dstNet); 313aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 314aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 3154095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3164095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Find the route from a Collection of routes that best matches a given address. 3174095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * May return null if no routes are applicable. 3184095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param routes a Collection of RouteInfos to chose from 3194095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param dest the InetAddress your trying to get to 3204095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @return the RouteInfo from the Collection that best fits the given address 3214095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 3224095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @hide 3234095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 3244095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { 3254095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if ((routes == null) || (dest == null)) return null; 326aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 3274095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt RouteInfo bestRoute = null; 3284095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt // pick a longest prefix match under same address type 3294095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt for (RouteInfo route : routes) { 3304095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { 3314095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if ((bestRoute != null) && 3327dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti (bestRoute.mDestination.getPrefixLength() >= 3337dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti route.mDestination.getPrefixLength())) { 3344095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt continue; 3354095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 3364095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if (route.matches(dest)) bestRoute = route; 3374095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 338aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 3394095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt return bestRoute; 3404095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 34145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 342cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 343cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Returns a human-readable description of this object. 344cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 3454095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public String toString() { 3464095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt String val = ""; 3474095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if (mDestination != null) val = mDestination.toString(); 348cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran val += " ->"; 349cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran if (mGateway != null) val += " " + mGateway.getHostAddress(); 350cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran if (mInterface != null) val += " " + mInterface; 3514095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt return val; 352aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 353aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 354cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 355cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Compares this RouteInfo object against the specified object and indicates if they are equal. 356cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @return {@code true} if the objects are equal, {@code false} otherwise. 357cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 358be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville public boolean equals(Object obj) { 359be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville if (this == obj) return true; 360be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 361be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville if (!(obj instanceof RouteInfo)) return false; 362be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 363be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville RouteInfo target = (RouteInfo) obj; 364be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 3651806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return Objects.equals(mDestination, target.getDestination()) && 366386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt Objects.equals(mGateway, target.getGateway()) && 367386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt Objects.equals(mInterface, target.getInterface()); 368be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville } 369be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 370cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 371cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Returns a hashcode for this <code>RouteInfo</code> object. 372cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 373be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville public int hashCode() { 37464c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti return (mDestination.hashCode() * 41) 3754095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt + (mGateway == null ? 0 :mGateway.hashCode() * 47) 37664c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti + (mInterface == null ? 0 :mInterface.hashCode() * 67); 377be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville } 378be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 3794095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3804095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Implement the Parcelable interface 3814095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 3824095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public int describeContents() { 3834095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt return 0; 3844095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 3854095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt 3864095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3874095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Implement the Parcelable interface 3884095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 3894095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public void writeToParcel(Parcel dest, int flags) { 3901806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti dest.writeParcelable(mDestination, flags); 3911806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress(); 3921806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti dest.writeByteArray(gatewayBytes); 3934095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt dest.writeString(mInterface); 3944095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 3954095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt 3964095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3974095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Implement the Parcelable interface. 3984095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 399aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public static final Creator<RouteInfo> CREATOR = 400aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt new Creator<RouteInfo>() { 401aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public RouteInfo createFromParcel(Parcel in) { 4021806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti IpPrefix dest = in.readParcelable(null); 403aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 4041806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti InetAddress gateway = null; 40564c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti byte[] addr = in.createByteArray(); 40664c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti try { 4071806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti gateway = InetAddress.getByAddress(addr); 40864c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti } catch (UnknownHostException e) {} 409aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 41045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti String iface = in.readString(); 41145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 41245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti return new RouteInfo(dest, gateway, iface); 413aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 414aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 415aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public RouteInfo[] newArray(int size) { 416aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt return new RouteInfo[size]; 417aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 418aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt }; 419aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt} 420