NetworkUtils.java revision 31be7cf4c7aef140f2a576975a7fd31e062f6964
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.InetAddress;
20585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport java.net.Inet4Address;
21585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport java.net.Inet6Address;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.UnknownHostException;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport android.util.Log;
25585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Native methods for managing network interfaces.
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class NetworkUtils {
32585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
33585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    private static final String TAG = "NetworkUtils";
34585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
350900f3657664d9046e6723825fd32b244eef2b6cMike Lockwood    /** Bring the named network interface up. */
360900f3657664d9046e6723825fd32b244eef2b6cMike Lockwood    public native static int enableInterface(String interfaceName);
370900f3657664d9046e6723825fd32b244eef2b6cMike Lockwood
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Bring the named network interface down. */
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static int disableInterface(String interfaceName);
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
42585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Add a route to the routing table.
43585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     *
44585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param interfaceName the interface to route through.
45585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param dst the network or host to route to. May be IPv4 or IPv6, e.g.
46585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * "0.0.0.0" or "2001:4860::".
47585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param prefixLength the prefix length of the route.
48585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param gw the gateway to use, e.g., "192.168.251.1". If null,
49585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * indicates a directly-connected route.
50585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
51585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public native static int addRoute(String interfaceName, String dst,
52585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt          int prefixLength, String gw);
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Return the gateway address for the default route for the named interface. */
5547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    public static InetAddress getDefaultRoute(String interfaceName) {
5647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        int addr = getDefaultRouteNative(interfaceName);
57585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        return intToInetAddress(addr);
5847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
5947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    private native static int getDefaultRouteNative(String interfaceName);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Remove host routes that uses the named interface. */
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static int removeHostRoutes(String interfaceName);
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Remove the default route for the named interface. */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static int removeDefaultRoute(String interfaceName);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Reset any sockets that are connected via the named interface. */
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static int resetConnections(String interfaceName);
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Start the DHCP client daemon, in order to have it request addresses
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for the named interface, and then configure the interface with those
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * addresses. This call blocks until it obtains a result (either success
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or failure) from the daemon.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface to configure
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param ipInfo if the request succeeds, this object is filled in with
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the IP address information.
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
800216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    public native static boolean runDhcp(String interfaceName, DhcpInfoInternal ipInfo);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8331be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff     * Initiate renewal on the Dhcp client daemon. This call blocks until it obtains
8431be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff     * a result (either success or failure) from the daemon.
8531be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff     * @param interfaceName the name of the interface to configure
8631be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff     * @param ipInfo if the request succeeds, this object is filled in with
8731be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff     * the IP address information.
8831be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff     * @return {@code true} for success, {@code false} for failure
8931be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff     */
9031be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    public native static boolean runDhcpRenew(String interfaceName, DhcpInfoInternal ipInfo);
9131be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff
9231be7cf4c7aef140f2a576975a7fd31e062f6964Irfan Sheriff    /**
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shut down the DHCP client daemon.
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface for which the daemon
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should be stopped
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean stopDhcp(String interfaceName);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Release the current DHCP lease.
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface for which the lease should
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be released
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean releaseDhcpLease(String interfaceName);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the last DHCP-related error message that was recorded.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p/>NOTE: This string is not localized, but currently it is only
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * used in logging.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the most recent error message, if any
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static String getDhcpError();
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
117585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Convert a IPv4 address from an integer to an InetAddress.
11807481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     * @param hostAddress an int corresponding to the IPv4 address in network byte order
119585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
120585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public static InetAddress intToInetAddress(int hostAddress) {
121585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        byte[] addressBytes = { (byte)(0xff & hostAddress),
122585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 8)),
123585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 16)),
124585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 24)) };
12547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
12707481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson           return InetAddress.getByAddress(addressBytes);
12807481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson        } catch (UnknownHostException e) {
12907481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson           throw new AssertionError();
130585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
131585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    }
132585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
13396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /**
13496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * Convert a IPv4 address from an InetAddress to an integer
13596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @param inetAddr is an InetAddress corresponding to the IPv4 address
13696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @return the IP address as an integer in network byte order
13796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     */
13896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    public static int inetAddressToInt(InetAddress inetAddr)
13996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throws IllegalArgumentException {
14096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        byte [] addr = inetAddr.getAddress();
14196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (addr.length != 4) {
14296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throw new IllegalArgumentException("Not an IPv4 address");
14396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
14496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
14596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
14696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
14796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
14896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /**
14996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * Convert a network prefix length to an IPv4 netmask integer
15096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @param prefixLength
15196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @return the IPv4 netmask as an integer in network byte order
15296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     */
15396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    public static int prefixLengthToNetmaskInt(int prefixLength)
15496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throws IllegalArgumentException {
15596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (prefixLength < 0 || prefixLength > 32) {
15696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
15796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
15896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        int value = 0xffffffff << (32 - prefixLength);
15996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        return Integer.reverseBytes(value);
16096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
16196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
1620216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    /**
1630216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * Create an InetAddress from a string where the string must be a standard
1640216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * representation of a V4 or V6 address.  Avoids doing a DNS lookup on failure
1650216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * but it will throw an IllegalArgumentException in that case.
1660216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @param addrString
1670216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @return the InetAddress
1680216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @hide
1690216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     */
1700216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    public static InetAddress numericToInetAddress(String addrString)
1710216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            throws IllegalArgumentException {
172f5bbb5720454742e0e2f6ae489fa164845261cbfElliott Hughes        return InetAddress.parseNumericAddress(addrString);
1730216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    }
1740216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt
175585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
176585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Add a default route through the specified gateway.
177585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param interfaceName interface on which the route should be added
178585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param gw the IP address of the gateway to which the route is desired,
179585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @return {@code true} on success, {@code false} on failure
180585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
181585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public static boolean addDefaultRoute(String interfaceName, InetAddress gw) {
182585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        String dstStr;
183585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        String gwStr = gw.getHostAddress();
184585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
185585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        if (gw instanceof Inet4Address) {
186585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            dstStr = "0.0.0.0";
187585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        } else if (gw instanceof Inet6Address) {
188585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            dstStr = "::";
189585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        } else {
190585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            Log.w(TAG, "addDefaultRoute failure: address is neither IPv4 nor IPv6" +
191585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                       "(" + gwStr + ")");
192585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            return false;
193585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
194585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        return addRoute(interfaceName, dstStr, 0, gwStr) == 0;
195585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    }
196585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
197585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
198585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Add a host route.
199585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param interfaceName interface on which the route should be added
200585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param dst the IP address of the host to which the route is desired,
201585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * this should not be null.
202585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param gw the IP address of the gateway to which the route is desired,
203585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * if null, indicates a directly-connected route.
204585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @return {@code true} on success, {@code false} on failure
205585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
206585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public static boolean addHostRoute(String interfaceName, InetAddress dst,
207585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt          InetAddress gw) {
208585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        if (dst == null) {
209585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            Log.w(TAG, "addHostRoute: dst should not be null");
210585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            return false;
211585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
212585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
213585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        int prefixLength;
214585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        String dstStr = dst.getHostAddress();
215585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        String gwStr = (gw != null) ? gw.getHostAddress() : null;
216585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
217585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        if (dst instanceof Inet4Address) {
218585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            prefixLength = 32;
219585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        } else if (dst instanceof Inet6Address) {
220585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            prefixLength = 128;
221585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        } else {
222585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            Log.w(TAG, "addHostRoute failure: address is neither IPv4 nor IPv6" +
223585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                       "(" + dst + ")");
224585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            return false;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
226585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        return addRoute(interfaceName, dstStr, prefixLength, gwStr) == 0;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
229