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 *
32aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt * @hide
33aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt */
34aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltpublic class RouteInfo implements Parcelable {
35aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    /**
36aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     * The IP destination address for this route.
37aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     */
38aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private final LinkAddress mDestination;
39aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
40aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    /**
41aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     * The gateway address for this route.
42aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt     */
43aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private final InetAddress mGateway;
44aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
45aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private final boolean mIsDefault;
460a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private final boolean mIsHost;
47aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
48aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public RouteInfo(LinkAddress destination, InetAddress gateway) {
49aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (destination == null) {
5059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            if (gateway != null) {
5159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                if (gateway instanceof Inet4Address) {
5259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    destination = new LinkAddress(Inet4Address.ANY, 0);
53aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                } else {
5459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    destination = new LinkAddress(Inet6Address.ANY, 0);
55aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                }
5659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            } else {
5759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                // no destination, no gateway. invalid.
5859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                throw new RuntimeException("Invalid arguments passed in.");
5959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
60aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
618c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo        if (gateway == null) {
628c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo            if (destination.getAddress() instanceof Inet4Address) {
638c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo                gateway = Inet4Address.ANY;
648c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo            } else {
658c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo                gateway = Inet6Address.ANY;
668c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo            }
678c0b528a4746228461ead10f0d477345b607fef1Kazuhiro Ondo        }
68f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
69f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength());
70aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        mGateway = gateway;
71aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        mIsDefault = isDefault();
720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        mIsHost = isHost();
73aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
74aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
75aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public RouteInfo(InetAddress gateway) {
76f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        this(null, gateway);
77aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
78aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
7959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    public static RouteInfo makeHostRoute(InetAddress host) {
8059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        return makeHostRoute(host, null);
8159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
8259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
8359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway) {
8459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        if (host == null) return null;
8559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
8659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        if (host instanceof Inet4Address) {
8759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            return new RouteInfo(new LinkAddress(host, 32), gateway);
8859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        } else {
8959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            return new RouteInfo(new LinkAddress(host, 128), gateway);
9059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
9159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
9259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
930a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean isHost() {
940a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return (mGateway.equals(Inet4Address.ANY) || mGateway.equals(Inet6Address.ANY));
950a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
960a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
97aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private boolean isDefault() {
98aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        boolean val = false;
99aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mGateway != null) {
100aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (mGateway instanceof Inet4Address) {
101f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
102aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            } else {
103f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
104aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
105aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
106aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return val;
107aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
108aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
1090a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
110aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public LinkAddress getDestination() {
111aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return mDestination;
112aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
113aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
114aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public InetAddress getGateway() {
115aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return mGateway;
116aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
117aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
118aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public boolean isDefaultRoute() {
119aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return mIsDefault;
120aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
121aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
1220a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public boolean isHostRoute() {
1230a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return mIsHost;
1240a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
1250a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
126aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public String toString() {
127aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        String val = "";
128aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mDestination != null) val = mDestination.toString();
129aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mGateway != null) val += " -> " + mGateway.getHostAddress();
130aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return val;
131aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
132aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
133aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public int describeContents() {
134aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return 0;
135aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
136aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
137aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public void writeToParcel(Parcel dest, int flags) {
138aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mDestination == null) {
139aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 0);
140aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        } else {
141aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 1);
142aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByteArray(mDestination.getAddress().getAddress());
143aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeInt(mDestination.getNetworkPrefixLength());
144aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
145aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
146aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        if (mGateway == null) {
147aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 0);
148aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        } else {
149aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByte((byte) 1);
150aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeByteArray(mGateway.getAddress());
151aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
152aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    }
153aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
154be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    @Override
155be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    public boolean equals(Object obj) {
156be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        if (this == obj) return true;
157be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
158be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        if (!(obj instanceof RouteInfo)) return false;
159be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
160be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        RouteInfo target = (RouteInfo) obj;
161be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
162be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        boolean sameDestination = ( mDestination == null) ?
163be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                target.getDestination() == null
164be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                : mDestination.equals(target.getDestination());
165be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
166be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        boolean sameAddress = (mGateway == null) ?
167be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                target.getGateway() == null
168be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville                : mGateway.equals(target.getGateway());
169be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
170be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        return sameDestination && sameAddress
171be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            && mIsDefault == target.mIsDefault;
172be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    }
173be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
174be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    @Override
175be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    public int hashCode() {
176be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville        return (mDestination == null ? 0 : mDestination.hashCode())
177be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            + (mGateway == null ? 0 :mGateway.hashCode())
178be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            + (mIsDefault ? 3 : 7);
179be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville    }
180be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville
181aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public static final Creator<RouteInfo> CREATOR =
182aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        new Creator<RouteInfo>() {
183aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        public RouteInfo createFromParcel(Parcel in) {
184aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            InetAddress destAddr = null;
185aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            int prefix = 0;
186aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            InetAddress gateway = null;
187aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
188aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (in.readByte() == 1) {
189aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                byte[] addr = in.createByteArray();
190aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                prefix = in.readInt();
191aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
192aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                try {
193aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    destAddr = InetAddress.getByAddress(addr);
194aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                } catch (UnknownHostException e) {}
195aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
196aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
197aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (in.readByte() == 1) {
198aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                byte[] addr = in.createByteArray();
199aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
200aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                try {
201aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    gateway = InetAddress.getByAddress(addr);
202aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                } catch (UnknownHostException e) {}
203aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
204aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
205aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            LinkAddress dest = null;
206aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
207aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (destAddr != null) {
208aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                dest = new LinkAddress(destAddr, prefix);
209aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            }
210aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
211aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            return new RouteInfo(dest, gateway);
212aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
213aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt
214aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        public RouteInfo[] newArray(int size) {
215aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            return new RouteInfo[size];
216aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        }
217aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    };
218f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
219f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    private boolean matches(InetAddress destination) {
220f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if (destination == null) return false;
221f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
222f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        // if the destination is present and the route is default.
223f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        // return true
224f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if (isDefault()) return true;
225f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
226f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        // match the route destination and destination with prefix length
227f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
228f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                mDestination.getNetworkPrefixLength());
229f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
230f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return mDestination.getAddress().equals(dstNet);
231f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
232f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
233f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    /**
234f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * Find the route from a Collection of routes that best matches a given address.
235f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * May return null if no routes are applicable.
236f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @param routes a Collection of RouteInfos to chose from
237f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @param dest the InetAddress your trying to get to
238f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @return the RouteInfo from the Collection that best fits the given address
239f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     */
240f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
241f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if ((routes == null) || (dest == null)) return null;
242f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
243f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        RouteInfo bestRoute = null;
244f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        // pick a longest prefix match under same address type
245f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        for (RouteInfo route : routes) {
246f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
247f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                if ((bestRoute != null) &&
248f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                        (bestRoute.mDestination.getNetworkPrefixLength() >=
249f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                        route.mDestination.getNetworkPrefixLength())) {
250f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                    continue;
251f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                }
252f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                if (route.matches(dest)) bestRoute = route;
253f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            }
254f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
255f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return bestRoute;
256f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
257aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt}
258