Android examples for Network:IP Address
Create a new 6to4 tunnel interface.
/***************************************************************************** * Project: Android IPv6Config/*from w ww .ja va2 s . com*/ * 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); /** Identifier for starting the MTU option in the interface line. */ private final static String INTERFACE_MTU = "mtu"; /** 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 network interface addresses and options under modern Linux systems. */ private final static String ADDRESSES_COMMAND = " addr"; /** 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 "; /** Simply the shell command (and if necessary path) to execute a standard POSIX shell. */ public final static String SH_COMMAND = "sh"; /** Command to get and set network interface status under modern Linux systems (up/down mostly). */ private final static String SET_INTERFACE = " link set "; /** Option to set network interface up. */ private final static String UP = " up"; /** Option to add network interface / addresses / routes. */ private final static String ADD = " add "; /** Command to the "ip" binary to create a tunnel interface under modern Linux systems. */ private final static String ADD_TUNNEL_INTERFACE = " tunnel" + ADD; private final static String ADD_TUNNEL_INTERFACE_OPTIONS_1 = " mode sit remote any local "; private final static String ADD_TUNNEL_INTERFACE_OPTIONS_2 = " ttl 255 "; /** 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; /** Create a new 6to4 tunnel interface. * * @param iface The interface name to create. * @param localIPv4Endpoint The local IPv4 endpoint address to assign to the tunnel. * @param ipv6Prefix The 6to4 prefix derived from the endpoint address that will be * used to create the IPv6 address. * @param mtu The maximum transfer unit for the new interface. If a value * <=0 is passed as argument, a default of 1430 will be used. * @return true if successfully created and addresses and routes added, false otherwise. */ public static boolean create6to4TunnelInterface(String iface, Inet4Address localIPv4Endpoint, String ipv6Prefix, int mtu) { if (mtu <= 0) mtu = 1430; if (localIPv4Endpoint == null || ipv6Prefix == null || iface == null) { logger.severe("Unable to create 6to4 tunnel, null parameters"); return false; } String cmdTunnel = getIPCommandLocation() + ADD_TUNNEL_INTERFACE + iface + ADD_TUNNEL_INTERFACE_OPTIONS_1 + localIPv4Endpoint.getHostAddress() + ADD_TUNNEL_INTERFACE_OPTIONS_2; String cmdSetUp = getIPCommandLocation() + SET_INTERFACE + iface + UP + " " + INTERFACE_MTU + " " + mtu; /* Experienced IPv6 users will wonder why the netmask for sit0 is /16, not /64; * by setting the netmask to /16, you instruct your system to send packets * directly to the IPv4 address of other 6to4 users; if it was /64, you'd send * packets via the nearest relay router, increasing latency. */ String cmd6to4Addr = getIPCommandLocation() + OPTION_IPv6_ONLY + ADDRESSES_COMMAND + ADD + ipv6Prefix + "::/16 dev " + iface; String cmd6to4Route1 = getIPCommandLocation() + OPTION_IPv6_ONLY + ROUTES_COMMAND + ADD + " 0:0:0:0:0:ffff::/96 dev " + iface + " metric 1"; String cmd6to4Route2 = getIPCommandLocation() + OPTION_IPv6_ONLY + ROUTES_COMMAND + ADD + " 2000::/3 via ::192.88.99.1 dev " + iface + " metric 1"; try { logger.finer("Trying to create 6to4 tunnel interface " + iface + " with local endpoint " + localIPv4Endpoint.getHostAddress() + " for prefix " + ipv6Prefix + " with MTU " + mtu); if (Command.executeCommand(SH_COMMAND, true, cmdTunnel, null, null) != 0) { logger.severe("Unable to create tunnel interface " + iface); return false; } if (Command.executeCommand(SH_COMMAND, true, cmdSetUp, null, null) != 0) { logger.severe("Unable to set tunnel interface " + iface + " up with MTU " + mtu); return false; } if (Command.executeCommand(SH_COMMAND, true, cmd6to4Addr, null, null) != 0) { logger.severe("Unable to add 6to4 address " + ipv6Prefix + " to tunnel interface " + iface); return false; } if (Command.executeCommand(SH_COMMAND, true, cmd6to4Route1, null, null) != 0) { logger.severe("Unable to add 6to4 route 1 to tunnel interface " + iface); return false; } if (Command.executeCommand(SH_COMMAND, true, cmd6to4Route2, null, null) != 0) { logger.severe("Unable to add 6to4 route 2 to tunnel interface " + iface); return false; } logger.info("Successfully created 6to4 tunnel interface " + iface + " with local endpoint " + localIPv4Endpoint.getHostAddress() + " for prefix " + ipv6Prefix + " with MTU " + mtu); return true; } catch (IOException e) { logger.severe("Unable to execute system command, tunnel interface not deleted (access privileges missing?) " + e); return false; } catch (InterruptedException e) { return false; } } /** 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; } /** Helper function to try a list of paths with a command to verify if "ip addr" can be executed correctly. * * @return true if a working "ip addr" call could be made, false otherwise. If true is returned, * the working full binary path is stored in ipBinaryLocation. * @see ipBinaryLocation */ private static boolean tryIPBinaries(String[] paths, String cmd, String cmd2) { for (String path : paths) { String binary = path + cmd; // sanity check: can we actually execute our command? logger.finer("Checking for availibility of command '" + binary + "'"); if (new File(binary).canRead()) { if (cmd2 != null) binary = binary + " " + cmd2; /* second sanity check: does this binary work? * (E.g. on the Samsung Galaxy S2, there actually is a binary under * /system/bin/ip that claims to work, but doesn't). */ try { logger.fine("Trying to execute cmd '" + binary + ADDRESSES_COMMAND + "'"); Command.executeCommand(binary + ADDRESSES_COMMAND, false, false, null); logger.fine("Found working ip binary in " + binary); ipBinaryLocation = binary; return true; } catch (Exception e) { logger.warning("Found ip binary in " + binary + ", but does not behave as expected. Trying next location."); } } ipBinaryTriedPaths = ipBinaryTriedPaths + " '" + binary + "'"; } return false; } }