RouteInfo.java revision fdadc4e242d987c09007df274e01fe678a82331f
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;
28f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
29aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt/**
30aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * A simple container for route information.
31aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt *
3245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * In order to be used, a route must have a destination prefix and:
3345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti *
3445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * - A gateway address (next-hop, for gatewayed routes), or
3545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * - An interface (for directly-connected routes), or
3645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * - Both a gateway and an interface.
3745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti *
3845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * This class does not enforce these constraints because there is code that
3945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * uses RouteInfo objects to store directly-connected routes without interfaces.
4045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * Such objects cannot be used directly, but can be put into a LinkProperties
4145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti * object which then specifies the interface.
4245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti *
43aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * @hide
44aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt */
45aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltpublic class RouteInfo implements Parcelable {
46aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    /**
47aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     * The IP destination address for this route.
48aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     */
49aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private final LinkAddress mDestination;
50aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
51aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    /**
52aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     * The gateway address for this route.
53aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     */
54aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private final InetAddress mGateway;
55aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
5645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    /**
5745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * The interface for this route.
5845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     */
5945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    private final String mInterface;
6045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
61aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private final boolean mIsDefault;
620a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private final boolean mIsHost;
63aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
6445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    /**
6545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * Constructs a RouteInfo object.
6645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     *
67574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti     * If destination is null, then gateway must be specified and the
6845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * constructed route is either the IPv4 default route <code>0.0.0.0</code>
6945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * if @gateway is an instance of {@link Inet4Address}, or the IPv6 default
70574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti     * route <code>::/0</code> if gateway is an instance of
7145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * {@link Inet6Address}.
7245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     *
73574b00a3621d1e6db560ea2f4593a0ae7a90e145Lorenzo Colitti     * destination and gateway may not both be null.
7445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     *
7545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * @param destination the destination prefix
7645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * @param gateway the IP address to route packets through
7745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     * @param iface the interface name to send packets on
7845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti     */
7945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
80aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (destination == null) {
8159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            if (gateway != null) {
8259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                if (gateway instanceof Inet4Address) {
8359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    destination = new LinkAddress(Inet4Address.ANY, 0);
84aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                } else {
8559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    destination = new LinkAddress(Inet6Address.ANY, 0);
86aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                }
8759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            } else {
8859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                // no destination, no gateway. invalid.
8945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti                throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," +
9045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti                                                   destination);
9159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
92aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
938c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo        if (gateway == null) {
948c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo            if (destination.getAddress() instanceof Inet4Address) {
958c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo                gateway = Inet4Address.ANY;
968c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo            } else {
978c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo                gateway = Inet6Address.ANY;
988c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo            }
998c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo        }
100f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
101f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength());
102aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        mGateway = gateway;
10345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        mInterface = iface;
104aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        mIsDefault = isDefault();
1050a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        mIsHost = isHost();
106aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
107aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
10845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    public RouteInfo(LinkAddress destination, InetAddress gateway) {
10945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        this(destination, gateway, null);
11045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    }
11145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
112aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public RouteInfo(InetAddress gateway) {
11345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        this(null, gateway, null);
114aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
115aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
1164717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    public RouteInfo(LinkAddress host) {
11745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        this(host, null, null);
1184717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    }
1194717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt
120e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti    public static RouteInfo makeHostRoute(InetAddress host, String iface) {
121e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti        return makeHostRoute(host, null, iface);
12259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
12359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
124e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti    public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) {
12559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        if (host == null) return null;
12659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
12759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        if (host instanceof Inet4Address) {
128e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti            return new RouteInfo(new LinkAddress(host, 32), gateway, iface);
12959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        } else {
130e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti            return new RouteInfo(new LinkAddress(host, 128), gateway, iface);
13159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
13259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
13359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
1340a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean isHost() {
135fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti        return (mDestination.getAddress() instanceof Inet4Address &&
136fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti                mDestination.getNetworkPrefixLength() == 32) ||
137fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti               (mDestination.getAddress() instanceof Inet6Address &&
138fdadc4e242d987c09007df274e01fe678a82331fLorenzo Colitti                mDestination.getNetworkPrefixLength() == 128);
1390a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
1400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
141aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private boolean isDefault() {
142aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        boolean val = false;
143aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mGateway != null) {
144aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (mGateway instanceof Inet4Address) {
145f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
146aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            } else {
147f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
148aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
149aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
150aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return val;
151aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
152aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
1530a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
154aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public LinkAddress getDestination() {
155aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return mDestination;
156aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
157aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
158aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public InetAddress getGateway() {
159aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return mGateway;
160aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
161aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
16245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    public String getInterface() {
16345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        return mInterface;
16445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    }
16545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
166aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public boolean isDefaultRoute() {
167aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return mIsDefault;
168aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
169aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
1700a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public boolean isHostRoute() {
1710a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return mIsHost;
1720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
1730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
174aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public String toString() {
175aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        String val = "";
176aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mDestination != null) val = mDestination.toString();
177aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mGateway != null) val += " -> " + mGateway.getHostAddress();
178aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return val;
179aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
180aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
181aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public int describeContents() {
182aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return 0;
183aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
184aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
185aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public void writeToParcel(Parcel dest, int flags) {
186aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mDestination == null) {
187aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 0);
188aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        } else {
189aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 1);
190aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByteArray(mDestination.getAddress().getAddress());
191aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeInt(mDestination.getNetworkPrefixLength());
192aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
193aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
194aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mGateway == null) {
195aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 0);
196aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        } else {
197aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 1);
198aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByteArray(mGateway.getAddress());
199aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
20045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
20145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        dest.writeString(mInterface);
202aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
203aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
204be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    @Override
205be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    public boolean equals(Object obj) {
206be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        if (this == obj) return true;
207be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
208be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        if (!(obj instanceof RouteInfo)) return false;
209be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
210be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        RouteInfo target = (RouteInfo) obj;
211be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
212be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        boolean sameDestination = ( mDestination == null) ?
213be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                target.getDestination() == null
214be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                : mDestination.equals(target.getDestination());
215be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
216be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        boolean sameAddress = (mGateway == null) ?
217be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                target.getGateway() == null
218be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                : mGateway.equals(target.getGateway());
219be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
22045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        boolean sameInterface = (mInterface == null) ?
22145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti                target.getInterface() == null
22245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti                : mInterface.equals(target.getInterface());
22345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
22445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        return sameDestination && sameAddress && sameInterface
225be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            && mIsDefault == target.mIsDefault;
226be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    }
227be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
228be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    @Override
229be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    public int hashCode() {
23045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        return (mDestination == null ? 0 : mDestination.hashCode() * 41)
23145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            + (mGateway == null ? 0 :mGateway.hashCode() * 47)
23245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            + (mInterface == null ? 0 :mInterface.hashCode() * 67)
233be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            + (mIsDefault ? 3 : 7);
234be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    }
235be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
236aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public static final Creator<RouteInfo> CREATOR =
237aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        new Creator<RouteInfo>() {
238aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        public RouteInfo createFromParcel(Parcel in) {
239aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            InetAddress destAddr = null;
240aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            int prefix = 0;
241aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            InetAddress gateway = null;
242aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
243aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (in.readByte() == 1) {
244aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                byte[] addr = in.createByteArray();
245aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                prefix = in.readInt();
246aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
247aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                try {
248aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    destAddr = InetAddress.getByAddress(addr);
249aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                } catch (UnknownHostException e) {}
250aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
251aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
252aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (in.readByte() == 1) {
253aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                byte[] addr = in.createByteArray();
254aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
255aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                try {
256aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    gateway = InetAddress.getByAddress(addr);
257aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                } catch (UnknownHostException e) {}
258aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
259aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
26045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            String iface = in.readString();
26145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
262aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            LinkAddress dest = null;
263aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
264aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (destAddr != null) {
265aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                dest = new LinkAddress(destAddr, prefix);
266aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
267aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
26845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            return new RouteInfo(dest, gateway, iface);
269aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
270aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
271aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        public RouteInfo[] newArray(int size) {
272aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            return new RouteInfo[size];
273aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
274aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    };
275f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
27645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    protected boolean matches(InetAddress destination) {
277f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if (destination == null) return false;
278f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
279f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        // match the route destination and destination with prefix length
280f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
281f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                mDestination.getNetworkPrefixLength());
282f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
283f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return mDestination.getAddress().equals(dstNet);
284f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
285f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
286f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    /**
287f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * Find the route from a Collection of routes that best matches a given address.
288f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * May return null if no routes are applicable.
289f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @param routes a Collection of RouteInfos to chose from
290f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @param dest the InetAddress your trying to get to
291f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @return the RouteInfo from the Collection that best fits the given address
292f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     */
293f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
294f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if ((routes == null) || (dest == null)) return null;
295f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
296f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        RouteInfo bestRoute = null;
297f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        // pick a longest prefix match under same address type
298f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        for (RouteInfo route : routes) {
299f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
300f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                if ((bestRoute != null) &&
301f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                        (bestRoute.mDestination.getNetworkPrefixLength() >=
302f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                        route.mDestination.getNetworkPrefixLength())) {
303f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                    continue;
304f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                }
305f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                if (route.matches(dest)) bestRoute = route;
306f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            }
307f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
308f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return bestRoute;
309f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
310aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt}
311