Determine if a suitable IPv6 default route is set. - Android Network

Android examples for Network:IPv6

Description

Determine if a suitable IPv6 default route is set.

Demo Code

/*****************************************************************************
 *  Project: Android IPv6Config//from   w w  w.  j  a v a2 s .  c  o m
 *  Description: Android application to change IPv6 kernel configuration
 *  Author: Ren? Mayrhofer
 *  Copyright: Ren? Mayrhofer, 2011-2014
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 
 * as published by the Free Software Foundation.
 *****************************************************************************/
import java.io.File;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main{
    /** Our logger for this class. */
    private final static Logger logger = java.util.logging.Logger
            .getLogger(Constants.LOG_TAG);
    /** Identifies the gateway of a route. */
    private final static String ROUTE_GATEWAY = "via";
    /** Identifies the device of a route. */
    private final static String ROUTE_DEVICE = "dev";
    /** Search for the "ip" and "busybox" binaries at these locations. */
    public final static String[] LINUX_BINARY_LOCATIONS = { "/sbin/",
            "/bin/", "/system/bin/", "/system/xbin/" };
    /** Preferred is to use the "ip" binary directly. 
     * @see BUSYBOX_BINARY_PREFIX
     */
    public final static String IP_BINARY = "ip";
    /** But if no (working) ip binary can be found, then try to use busybox with an "ip" applet.
     * @see IP_BINARY
     */
    public final static String BUSYBOX_BINARY = "busybox";
    /** Command to get and set routes under modern Linux systems. */
    private final static String ROUTES_COMMAND = " route";
    /** Option to select only IPv6 addresses/routes. */
    private final static String OPTION_IPv6_ONLY = " -6 ";
    /** Static initializer: find out where to call the "ip" binary from and remember for future use. */
    private static String ipBinaryLocation = null;
    private static String ipBinaryTriedPaths = null;
    /** Determine if a suitable IPv6 default route is set.
     * 
     * @return true if an IPv6 default route can be found, false otherwise.
     */
    public static boolean existsIPv6DefaultRoute() {
        return getIfacesWithIPv6DefaultRoute().size() > 0;
    }
    /** Determine which interfaces have an IPv6 default route set.
     * 
     * @return the list of interfaces with an IPv6 default route.
     */
    public static LinkedList<String> getIfacesWithIPv6DefaultRoute() {
        LinkedList<String> ifaces = new LinkedList<String>();
        LinkedList<RouteDetail> routes;
        try {
            routes = LinuxIPCommandHelper.getRouteOutput(true);
            for (RouteDetail route : routes) {
                if (route.target.equalsIgnoreCase("default")
                        || route.target.equals("::/0")
                        || route.target.equals("2000::/3") // with IPv6, a route prefix of 2000::/3 is currently enough as a default route
                ) {
                    // ok, default route found
                    logger.info("Found default IPv6 route " + route.target
                            + " pointing to gateway '" + route.gateway
                            + "' on interface '" + route.iface + "'");
                    ifaces.add(route.iface);
                }
            }

            if (ifaces.size() == 0)
                logger.info("Unable to find any IPv6 default route");
        } catch (IOException e) {
            logger.warning("Unable to query Linux IPv4 main routing table"
                    + e);
        }
        return ifaces;
    }
    /** Returns the list of routes in the main routing table. 
     *  
     * @param queryIPv6 If true, then IPv6 routes are queried. If false, then IPv4 routes are queried.
     */
    public static LinkedList<RouteDetail> getRouteOutput(boolean queryIPv6)
            throws IOException {
        String cmd = getIPCommandLocation()
                + (queryIPv6 ? OPTION_IPv6_ONLY : "") + ROUTES_COMMAND;
        StringTokenizer lines = null;
        LinkedList<RouteDetail> list = new LinkedList<RouteDetail>();

        logger.warning("Acquiring route details with command '" + cmd + "'");

        try {
            lines = new StringTokenizer(Command.executeCommand(cmd, false,
                    false, null), "\n");
        } catch (Exception e) {
            logger.log(Level.WARNING,
                    "Tried to parse routes, but could not", e);
        }

        RouteDetail cur = null;
        while (lines != null && lines.hasMoreTokens()) {
            String line = lines.nextToken();
            logger.finest("getRouteOutput: parsing line '" + line + "'");

            StringTokenizer fields = new StringTokenizer(line, " \t");

            // the first field is always the target
            cur = new RouteDetail();
            cur.fullRouteLine = line;
            cur.target = fields.nextToken();

            // then we get options defined by "dev" or "via" (and others that we ignore)
            while (fields.hasMoreTokens()) {
                String opt = fields.nextToken().trim();
                logger.finest("getRouteOutput: trying to parse option '"
                        + opt + "'");

                if (opt.equals(ROUTE_GATEWAY) && fields.hasMoreTokens()) {
                    cur.gateway = InetAddress.getByName(fields.nextToken()
                            .trim());
                    logger.finest("getRouteOutput: found gateway "
                            + cur.gateway + " for target " + cur.target);
                } else if (opt.equals(ROUTE_DEVICE)
                        && fields.hasMoreTokens()) {
                    cur.iface = fields.nextToken().trim();
                    logger.finest("getRouteOutput: found interface "
                            + cur.iface + " for target " + cur.target);
                } else {
                    logger.finest("getRouteOutput: ignoring unknown option '"
                            + opt
                            + "' or no further field in string. Cannot parse.");
                }
            }

            // line finished, add route to list
            list.add(cur);
        }

        return list;
    }
    /** Helper to locate a usable "ip" command or null if none is found. */
    public static String getIPCommandLocation() {
        if (ipBinaryLocation == null) {
            ipBinaryTriedPaths = "";

            if (!tryIPBinaries(LINUX_BINARY_LOCATIONS, IP_BINARY, null)
                    && !tryIPBinaries(LINUX_BINARY_LOCATIONS,
                            BUSYBOX_BINARY, IP_BINARY))
                logger.severe("Could not find ip binary in"
                        + ipBinaryTriedPaths
                        + ", will be unable to read network interface details");
        }
        return ipBinaryLocation;
    }
}

Related Tutorials