RouteInfo.java revision 8c0b528a4746228461ead10f0d477345b607fef1
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.net; 18 19import android.os.Parcel; 20import android.os.Parcelable; 21 22import java.net.UnknownHostException; 23import java.net.InetAddress; 24import java.net.Inet4Address; 25import java.net.Inet6Address; 26 27import java.util.Collection; 28 29/** 30 * A simple container for route information. 31 * 32 * @hide 33 */ 34public class RouteInfo implements Parcelable { 35 /** 36 * The IP destination address for this route. 37 */ 38 private final LinkAddress mDestination; 39 40 /** 41 * The gateway address for this route. 42 */ 43 private final InetAddress mGateway; 44 45 private final boolean mIsDefault; 46 47 public RouteInfo(LinkAddress destination, InetAddress gateway) { 48 if (destination == null) { 49 try { 50 if (gateway != null) { 51 if (gateway instanceof Inet4Address) { 52 destination = new LinkAddress(Inet4Address.ANY, 0); 53 } else { 54 destination = new LinkAddress(Inet6Address.ANY, 0); 55 } 56 } else { 57 // no destination, no gateway. invalid. 58 throw new RuntimeException("Invalid arguments passed in."); 59 } 60 } catch (Exception e) {} 61 } 62 if (gateway == null) { 63 if (destination.getAddress() instanceof Inet4Address) { 64 gateway = Inet4Address.ANY; 65 } else { 66 gateway = Inet6Address.ANY; 67 } 68 } 69 mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(), 70 destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength()); 71 mGateway = gateway; 72 mIsDefault = isDefault(); 73 } 74 75 public RouteInfo(InetAddress gateway) { 76 this(null, gateway); 77 } 78 79 private boolean isDefault() { 80 boolean val = false; 81 if (mGateway != null) { 82 if (mGateway instanceof Inet4Address) { 83 val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0); 84 } else { 85 val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0); 86 } 87 } 88 return val; 89 } 90 91 public LinkAddress getDestination() { 92 return mDestination; 93 } 94 95 public InetAddress getGateway() { 96 return mGateway; 97 } 98 99 public boolean isDefaultRoute() { 100 return mIsDefault; 101 } 102 103 public String toString() { 104 String val = ""; 105 if (mDestination != null) val = mDestination.toString(); 106 if (mGateway != null) val += " -> " + mGateway.getHostAddress(); 107 return val; 108 } 109 110 public int describeContents() { 111 return 0; 112 } 113 114 public void writeToParcel(Parcel dest, int flags) { 115 if (mDestination == null) { 116 dest.writeByte((byte) 0); 117 } else { 118 dest.writeByte((byte) 1); 119 dest.writeByteArray(mDestination.getAddress().getAddress()); 120 dest.writeInt(mDestination.getNetworkPrefixLength()); 121 } 122 123 if (mGateway == null) { 124 dest.writeByte((byte) 0); 125 } else { 126 dest.writeByte((byte) 1); 127 dest.writeByteArray(mGateway.getAddress()); 128 } 129 } 130 131 public static final Creator<RouteInfo> CREATOR = 132 new Creator<RouteInfo>() { 133 public RouteInfo createFromParcel(Parcel in) { 134 InetAddress destAddr = null; 135 int prefix = 0; 136 InetAddress gateway = null; 137 138 if (in.readByte() == 1) { 139 byte[] addr = in.createByteArray(); 140 prefix = in.readInt(); 141 142 try { 143 destAddr = InetAddress.getByAddress(addr); 144 } catch (UnknownHostException e) {} 145 } 146 147 if (in.readByte() == 1) { 148 byte[] addr = in.createByteArray(); 149 150 try { 151 gateway = InetAddress.getByAddress(addr); 152 } catch (UnknownHostException e) {} 153 } 154 155 LinkAddress dest = null; 156 157 if (destAddr != null) { 158 dest = new LinkAddress(destAddr, prefix); 159 } 160 161 return new RouteInfo(dest, gateway); 162 } 163 164 public RouteInfo[] newArray(int size) { 165 return new RouteInfo[size]; 166 } 167 }; 168 169 private boolean matches(InetAddress destination) { 170 if (destination == null) return false; 171 172 // if the destination is present and the route is default. 173 // return true 174 if (isDefault()) return true; 175 176 // match the route destination and destination with prefix length 177 InetAddress dstNet = NetworkUtils.getNetworkPart(destination, 178 mDestination.getNetworkPrefixLength()); 179 180 return mDestination.getAddress().equals(dstNet); 181 } 182 183 /** 184 * Find the route from a Collection of routes that best matches a given address. 185 * May return null if no routes are applicable. 186 * @param routes a Collection of RouteInfos to chose from 187 * @param dest the InetAddress your trying to get to 188 * @return the RouteInfo from the Collection that best fits the given address 189 */ 190 public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { 191 if ((routes == null) || (dest == null)) return null; 192 193 RouteInfo bestRoute = null; 194 // pick a longest prefix match under same address type 195 for (RouteInfo route : routes) { 196 if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { 197 if ((bestRoute != null) && 198 (bestRoute.mDestination.getNetworkPrefixLength() >= 199 route.mDestination.getNetworkPrefixLength())) { 200 continue; 201 } 202 if (route.matches(dest)) bestRoute = route; 203 } 204 } 205 return bestRoute; 206 } 207} 208