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 654b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 664b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti /** Unicast route. @hide */ 674b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti public static final int RTN_UNICAST = 1; 684b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 694b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti /** Unreachable route. @hide */ 704b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti public static final int RTN_UNREACHABLE = 7; 714b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 724b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti /** Throw route. @hide */ 734b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti public static final int RTN_THROW = 9; 744b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 754b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti /** 764b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * The type of this route; one of the RTN_xxx constants above. 774b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti */ 784b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti private final int mType; 794b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 804b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // Derived data members. 814b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // TODO: remove these. 820a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt private final boolean mIsHost; 83ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt private final boolean mHasGateway; 84aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 8545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti /** 8645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * Constructs a RouteInfo object. 8745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * 88574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti * If destination is null, then gateway must be specified and the 8945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * constructed route is either the IPv4 default route <code>0.0.0.0</code> 904095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default 91574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti * route <code>::/0</code> if gateway is an instance of 9245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * {@link Inet6Address}. 93386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * <p> 94574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti * destination and gateway may not both be null. 9545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * 9645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * @param destination the destination prefix 9745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * @param gateway the IP address to route packets through 9845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * @param iface the interface name to send packets on 99cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 100cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 101cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 1024b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti public RouteInfo(IpPrefix destination, InetAddress gateway, String iface, int type) { 1034b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti switch (type) { 1044b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti case RTN_UNICAST: 1054b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti case RTN_UNREACHABLE: 1064b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti case RTN_THROW: 1074b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // TODO: It would be nice to ensure that route types that don't have nexthops or 1084b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // interfaces, such as unreachable or throw, can't be created if an interface or 1094b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // a gateway is specified. This is a bit too complicated to do at the moment 1104b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // because: 1114b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // 1124b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // - LinkProperties sets the interface on routes added to it, and modifies the 1134b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // interfaces of all the routes when its interface name changes. 1144b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // - Even when the gateway is null, we store a non-null gateway here. 1154b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // 1164b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti // For now, we just rely on the code that sets routes to do things properly. 1174b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti break; 1184b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti default: 1194b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti throw new IllegalArgumentException("Unknown route type " + type); 1204b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } 1214b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 122aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt if (destination == null) { 12359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (gateway != null) { 12459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (gateway instanceof Inet4Address) { 1251806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti destination = new IpPrefix(Inet4Address.ANY, 0); 126aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } else { 1271806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti destination = new IpPrefix(Inet6Address.ANY, 0); 128aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 12959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } else { 13059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt // no destination, no gateway. invalid. 13145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," + 13245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti destination); 13359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 134aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 1351806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti // TODO: set mGateway to null if there is no gateway. This is more correct, saves space, and 1361806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti // matches the documented behaviour. Before we can do this we need to fix all callers (e.g., 1371806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti // ConnectivityService) to stop doing things like r.getGateway().equals(), ... . 1388c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo if (gateway == null) { 1398c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo if (destination.getAddress() instanceof Inet4Address) { 1408c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo gateway = Inet4Address.ANY; 1418c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo } else { 1428c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo gateway = Inet6Address.ANY; 1438c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo } 1448c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo } 145ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt mHasGateway = (!gateway.isAnyLocalAddress()); 146ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt 147386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt if ((destination.getAddress() instanceof Inet4Address && 148386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt (gateway instanceof Inet4Address == false)) || 149386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt (destination.getAddress() instanceof Inet6Address && 150386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt (gateway instanceof Inet6Address == false))) { 151386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt throw new IllegalArgumentException("address family mismatch in RouteInfo constructor"); 152386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt } 1531806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti mDestination = destination; // IpPrefix objects are immutable. 1541806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti mGateway = gateway; // InetAddress objects are immutable. 1551806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti mInterface = iface; // Strings are immutable. 1564b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti mType = type; 1570a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt mIsHost = isHost(); 158aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 159aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 1604095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 1614b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * @hide 1624b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti */ 1634b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) { 1644b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti this(destination, gateway, iface, RTN_UNICAST); 1654b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } 1664b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 1674b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti /** 1681806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti * @hide 1691806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti */ 1701806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { 1711806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti this(destination == null ? null : 1721806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti new IpPrefix(destination.getAddress(), destination.getPrefixLength()), 1731806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti gateway, iface); 1741806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti } 1751806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti 1761806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti /** 1774095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Constructs a {@code RouteInfo} object. 1784095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 1794095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * If destination is null, then gateway must be specified and the 1804095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * constructed route is either the IPv4 default route <code>0.0.0.0</code> 1814095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default 1824095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}. 1834095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * <p> 1844095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Destination and gateway may not both be null. 1854095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 186cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @param destination the destination address and prefix in an {@link IpPrefix} 1874095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param gateway the {@link InetAddress} to route packets through 188cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 189cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 190cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 191cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public RouteInfo(IpPrefix destination, InetAddress gateway) { 192cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran this(destination, gateway, null); 193cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran } 194cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran 195cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 196cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 1974b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * 1984b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * TODO: Remove this. 1994095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 20045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti public RouteInfo(LinkAddress destination, InetAddress gateway) { 20145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti this(destination, gateway, null); 20245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti } 20345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 2044095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2054095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Constructs a default {@code RouteInfo} object. 2064095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 2074095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param gateway the {@link InetAddress} to route packets through 208cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 209cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 2104095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 211aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public RouteInfo(InetAddress gateway) { 2121806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti this((IpPrefix) null, gateway, null); 213aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 214aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 2154095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2164095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Constructs a {@code RouteInfo} object representing a direct connected subnet. 2174095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 218cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @param destination the {@link IpPrefix} describing the address and prefix 219386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * length of the subnet. 220cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * 221cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 222cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 223cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public RouteInfo(IpPrefix destination) { 224cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran this(destination, null, null); 225cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran } 226cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran 227cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 228cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 2294095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 230386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt public RouteInfo(LinkAddress destination) { 231386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt this(destination, null, null); 2324717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt } 2334717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt 2344095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2354095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @hide 2364095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 2374b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti public RouteInfo(IpPrefix destination, int type) { 2384b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti this(destination, null, null, type); 2394b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } 2404b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 2414b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti /** 2424b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * @hide 2434b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti */ 244e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti public static RouteInfo makeHostRoute(InetAddress host, String iface) { 245e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti return makeHostRoute(host, null, iface); 24659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 24759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt 2484095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2494095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @hide 2504095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 251e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) { 25259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (host == null) return null; 25359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt 25459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt if (host instanceof Inet4Address) { 2551806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return new RouteInfo(new IpPrefix(host, 32), gateway, iface); 25659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } else { 2571806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return new RouteInfo(new IpPrefix(host, 128), gateway, iface); 25859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 25959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt } 26059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt 2610a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt private boolean isHost() { 262fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti return (mDestination.getAddress() instanceof Inet4Address && 2637dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti mDestination.getPrefixLength() == 32) || 264fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti (mDestination.getAddress() instanceof Inet6Address && 2657dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti mDestination.getPrefixLength() == 128); 2660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt } 2670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt 2684095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 269cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}. 2704095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 271cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @return {@link IpPrefix} specifying the destination. This is never {@code null}. 272cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 273cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public IpPrefix getDestination() { 2741806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return mDestination; 275cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran } 276cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran 277cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 278cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * TODO: Convert callers to use IpPrefix and then remove. 279cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @hide 2804095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 281cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran public LinkAddress getDestinationLinkAddress() { 2821806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength()); 283aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 284aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 2854095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 2864095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Retrieves the gateway or next hop {@link InetAddress} for this route. 2874095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 288386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @return {@link InetAddress} specifying the gateway or next hop. This may be 289e595b97ff470a5e92151350e4d7b4173032fde23Robert Greenwalt * {@code null} for a directly-connected route." 2904095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 291aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public InetAddress getGateway() { 292aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt return mGateway; 293aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 294aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 2954095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 296386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * Retrieves the interface used for this route if specified, else {@code null}. 2974095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 2984095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @return The name of the interface used for this route. 2994095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 30045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti public String getInterface() { 30145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti return mInterface; 30245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti } 30345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 3044095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3054b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * Retrieves the type of this route. 3064b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * 3074b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * @return The type of this route; one of the {@code RTN_xxx} constants defined in this class. 3084b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * 3094b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti * @hide 3104b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti */ 3114b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti public int getType() { 3124b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti return mType; 3134b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } 3144b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti 3154b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti /** 3164095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Indicates if this route is a default route (ie, has no destination specified). 3174095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 318386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @return {@code true} if the destination has a prefix length of 0. 3194095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 320aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public boolean isDefaultRoute() { 3214b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti return mType == RTN_UNICAST && mDestination.getPrefixLength() == 0; 32264c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti } 32364c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti 32464c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti /** 32564c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * Indicates if this route is an IPv4 default route. 32664c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * @hide 32764c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti */ 32864c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti public boolean isIPv4Default() { 32964c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti return isDefaultRoute() && mDestination.getAddress() instanceof Inet4Address; 33064c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti } 33164c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti 33264c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti /** 33364c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * Indicates if this route is an IPv6 default route. 33464c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti * @hide 33564c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti */ 33664c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti public boolean isIPv6Default() { 33764c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti return isDefaultRoute() && mDestination.getAddress() instanceof Inet6Address; 338aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 339aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 3404095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3414095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Indicates if this route is a host route (ie, matches only a single host address). 3424095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 343cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6, 344cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * respectively. 345386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @hide 3464095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 3470a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt public boolean isHostRoute() { 3480a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt return mIsHost; 3490a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt } 3500a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt 3514095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3524095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Indicates if this route has a next hop ({@code true}) or is directly-connected 3534095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * ({@code false}). 3544095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 3554095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @return {@code true} if a gateway is specified 356386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @hide 3574095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 358ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt public boolean hasGateway() { 359ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt return mHasGateway; 360ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt } 361ca441ee2f0d53c3d3a00b2a9aa96c064378fd535Robert Greenwalt 3624095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 363386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * Determines whether the destination and prefix of this route includes the specified 364386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * address. 365386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * 366386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @param destination A {@link InetAddress} to test to see if it would match this route. 367386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt * @return {@code true} if the destination and prefix length cover the given address. 3684095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 369386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt public boolean matches(InetAddress destination) { 370acc8c09d3a12d00b565a76acc26061172c3dd3c6Erik Kline return mDestination.contains(destination); 371aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 372aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 3734095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 3744095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Find the route from a Collection of routes that best matches a given address. 3754095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * May return null if no routes are applicable. 3764095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param routes a Collection of RouteInfos to chose from 3774095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @param dest the InetAddress your trying to get to 3784095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @return the RouteInfo from the Collection that best fits the given address 3794095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * 3804095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * @hide 3814095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 3824095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { 3834095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if ((routes == null) || (dest == null)) return null; 384aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 3854095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt RouteInfo bestRoute = null; 3864095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt // pick a longest prefix match under same address type 3874095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt for (RouteInfo route : routes) { 3884095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { 3894095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if ((bestRoute != null) && 3907dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti (bestRoute.mDestination.getPrefixLength() >= 3917dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti route.mDestination.getPrefixLength())) { 3924095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt continue; 3934095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 3944095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if (route.matches(dest)) bestRoute = route; 3954095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 396aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 3974095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt return bestRoute; 3984095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 39945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 400cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 401cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Returns a human-readable description of this object. 402cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 4034095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public String toString() { 4044095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt String val = ""; 4054095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt if (mDestination != null) val = mDestination.toString(); 4064b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti if (mType == RTN_UNREACHABLE) { 4074b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti val += " unreachable"; 4084b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } else if (mType == RTN_THROW) { 4094b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti val += " throw"; 4104b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } else { 4114b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti val += " ->"; 4124b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti if (mGateway != null) val += " " + mGateway.getHostAddress(); 4134b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti if (mInterface != null) val += " " + mInterface; 4144b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti if (mType != RTN_UNICAST) { 4154b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti val += " unknown type " + mType; 4164b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } 4174b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti } 4184095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt return val; 419aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 420aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 421cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 422cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Compares this RouteInfo object against the specified object and indicates if they are equal. 423cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * @return {@code true} if the objects are equal, {@code false} otherwise. 424cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 425be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville public boolean equals(Object obj) { 426be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville if (this == obj) return true; 427be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 428be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville if (!(obj instanceof RouteInfo)) return false; 429be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 430be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville RouteInfo target = (RouteInfo) obj; 431be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 4321806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti return Objects.equals(mDestination, target.getDestination()) && 433386aba8bd1c83bb8c088b8dd7b2024ba77c9c36cRobert Greenwalt Objects.equals(mGateway, target.getGateway()) && 4344b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti Objects.equals(mInterface, target.getInterface()) && 4354b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti mType == target.getType(); 436be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville } 437be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 438cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran /** 439cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran * Returns a hashcode for this <code>RouteInfo</code> object. 440cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran */ 441be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville public int hashCode() { 44264c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti return (mDestination.hashCode() * 41) 4434095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt + (mGateway == null ? 0 :mGateway.hashCode() * 47) 4444b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti + (mInterface == null ? 0 :mInterface.hashCode() * 67) 4454b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti + (mType * 71); 446be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville } 447be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville 4484095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 4494095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Implement the Parcelable interface 4504095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 4514095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public int describeContents() { 4524095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt return 0; 4534095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 4544095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt 4554095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 4564095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Implement the Parcelable interface 4574095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 4584095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt public void writeToParcel(Parcel dest, int flags) { 4591806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti dest.writeParcelable(mDestination, flags); 4601806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress(); 4611806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti dest.writeByteArray(gatewayBytes); 4624095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt dest.writeString(mInterface); 4634b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti dest.writeInt(mType); 4644095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt } 4654095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt 4664095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt /** 4674095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt * Implement the Parcelable interface. 4684095bd5a8811d4d8c2bb0efc28d9610629e27c89Robert Greenwalt */ 469aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public static final Creator<RouteInfo> CREATOR = 470aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt new Creator<RouteInfo>() { 471aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public RouteInfo createFromParcel(Parcel in) { 4721806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti IpPrefix dest = in.readParcelable(null); 473aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 4741806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti InetAddress gateway = null; 47564c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti byte[] addr = in.createByteArray(); 47664c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti try { 4771806b1fc25bcffaa005e72a55042031a42b168b1Lorenzo Colitti gateway = InetAddress.getByAddress(addr); 47864c43b1948a2b2fcd692cd4a48f031efbf7f7336Lorenzo Colitti } catch (UnknownHostException e) {} 479aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 48045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti String iface = in.readString(); 4814b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti int type = in.readInt(); 48245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti 4834b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti return new RouteInfo(dest, gateway, iface, type); 484aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 485aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt 486aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt public RouteInfo[] newArray(int size) { 487aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt return new RouteInfo[size]; 488aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt } 489aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt }; 490aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt} 491