package net.i2p.router.transport;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind { either expressed or implied.
* It probably won't make your computer catch on fire { or eat
* your children { but it might. Use at your own risk.
*
*/
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.data.router.RouterAddress;
import net.i2p.router.RouterContext;
/**
* @since IPv6
*/
public abstract class TransportUtil {
public static final String NTCP_IPV6_CONFIG = "i2np.ntcp.ipv6";
public static final String SSU_IPV6_CONFIG = "i2np.udp.ipv6";
public static final String PROP_IPV4_FIREWALLED = "i2np.ipv4.firewalled";
/** @since 0.9.28 */
public static final String PROP_IPV6_FIREWALLED = "i2np.ipv6.firewalled";
public enum IPv6Config {
/** IPv6 disabled */
IPV6_DISABLED("false"),
/** lower priority than IPv4 */
IPV6_NOT_PREFERRED("preferIPv4"),
/** equal priority to IPv4 */
IPV6_ENABLED("enable"),
/** higher priority than IPv4 */
IPV6_PREFERRED("preferIPv6"),
/** IPv4 disabled */
IPV6_ONLY("only");
private final String cfgstr;
IPv6Config(String cfgstr) {
this.cfgstr = cfgstr;
}
public String toConfigString() {
return cfgstr;
}
}
private static final Map<String, IPv6Config> BY_NAME = new HashMap<String, IPv6Config>();
public static final IPv6Config DEFAULT_IPV6_CONFIG = IPv6Config.IPV6_PREFERRED;
static {
for (IPv6Config cfg : IPv6Config.values()) {
BY_NAME.put(cfg.toConfigString(), cfg);
}
// alias
BY_NAME.put("true", IPv6Config.IPV6_ENABLED);
BY_NAME.put("disable", IPv6Config.IPV6_DISABLED);
}
public static IPv6Config getIPv6Config(RouterContext ctx, String transportStyle) {
String cfg;
if (transportStyle.equals("NTCP"))
cfg = ctx.getProperty(NTCP_IPV6_CONFIG);
else if (transportStyle.equals("SSU"))
cfg = ctx.getProperty(SSU_IPV6_CONFIG);
else
return DEFAULT_IPV6_CONFIG;
return getIPv6Config(cfg);
}
public static IPv6Config getIPv6Config(String cfg) {
if (cfg == null)
return DEFAULT_IPV6_CONFIG;
IPv6Config c = BY_NAME.get(cfg);
if (c != null)
return c;
return DEFAULT_IPV6_CONFIG;
}
/**
* This returns true if the force-firewalled setting is configured, false otherwise.
*
* @param transportStyle ignored
* @since 0.9.20
*/
public static boolean isIPv4Firewalled(RouterContext ctx, String transportStyle) {
return ctx.getBooleanProperty(PROP_IPV4_FIREWALLED);
}
/**
* This returns true if the force-firewalled setting is configured, false otherwise.
*
* @param transportStyle ignored
* @since 0.9.27, implemented in 0.9.28
*/
public static boolean isIPv6Firewalled(RouterContext ctx, String transportStyle) {
return ctx.getBooleanProperty(PROP_IPV6_FIREWALLED);
}
/**
* Addresses without a host (i.e. w/introducers)
* are assumed to be IPv4
*/
public static boolean isIPv6(RouterAddress addr) {
// do this the fast way, without calling getIP() to parse the host string
String host = addr.getHost();
return host != null && host.contains(":");
}
/**
* @param addr non-null
* @since IPv6 moved from TransportImpl
*/
public static boolean isPubliclyRoutable(byte addr[], boolean allowIPv6) {
return isPubliclyRoutable(addr, true, allowIPv6);
}
/**
* Ref: RFC 5735
*
* @param addr non-null
* @since IPv6
*/
public static boolean isPubliclyRoutable(byte addr[], boolean allowIPv4, boolean allowIPv6) {
if (I2PAppContext.getGlobalContext().getBooleanProperty("i2np.allowLocal"))
return true;
if (addr.length == 4) {
if (!allowIPv4)
return false;
int a0 = addr[0] & 0xFF;
// please keep sorted by IP
if (a0 == 0) return false;
if (a0 == 10) return false;
// 5/8 allocated to RIPE (30 November 2010)
//if ((addr[0]&0xFF) == 5) return false; // Hamachi
// Hamachi moved to 25/8 Nov. 2012
// Assigned to UK Ministry of Defence
// http://blog.logmein.com/products/changes-to-hamachi-on-november-19th
if (a0 == 25) return false;
if (a0 == 127) return false;
int a1 = addr[1] & 0xFF;
// Carrier Grade NAT RFC 6598
if (a0 == 100 && a1 >= 64 && a1 <= 127) return false;
// DHCP autoconfig RFC 3927
if (a0 == 169 && a1 == 254) return false;
if (a0 == 172 && a1 >= 16 && a1 <= 31) return false;
if (a0 == 192) {
if (a1 == 168) return false;
if (a1 == 0) {
int a2 = addr[2] & 0xFF;
// protocol assignment, documentation
// 192.0.0.2 seen in the wild, RFC 6333 "Dual-Stack Lite Broadband Deployments Following IPv4 Exhaustion"
if (a2 == 0 || a2 == 2) return false;
}
// 6to4 anycast
if (a1 == 88 && (addr[2] & 0xff) == 99) return false;
}
if (a0 == 198) {
// tests
if (a1 == 18 || a1 == 19) return false;
if (a1 == 51 && (addr[2] & 0xff) == 100) return false;
}
// test
if (a0 == 203 && a1 == 0 && (addr[2] & 0xff) == 113) return false;
if (a0 >= 224) return false; // no multicast
return true; // or at least possible to be true
} else if (addr.length == 16) {
if (allowIPv6) {
// loopback, broadcast,
// IPv4 compat ::xxxx:xxxx
if (addr[0] == 0)
return false;
if (addr[0] == 0x20) {
// disallow 2002::/16 (6to4 RFC 3056)
if (addr[1] == 0x02)
return false;
if (addr[1] == 0x01) {
// disallow 2001:0::/32 (Teredo RFC 4380)
if (addr[2] == 0x00 && addr[3] == 0x00)
return false;
// Documenation (example) RFC 3849
if (addr[2] == 0x0d && (addr[3] & 0xff) == 0xb8)
return false;
}
}
// disallow fc00::/8 and fd00::/8 (Unique local addresses RFC 4193)
// not recognized as local by InetAddress
if ((addr[0] & 0xfe) == 0xfc)
return false;
// Hamachi IPv6
if (addr[0] == 0x26 && addr[1] == 0x20 && addr[2] == 0x00 && (addr[3] & 0xff) == 0x9b)
return false;
// 6bone RFC 2471
if (addr[0] == 0x3f && (addr[1] & 0xff) == 0xfe)
return false;
try {
InetAddress ia = InetAddress.getByAddress(addr);
return
(!ia.isLinkLocalAddress()) &&
(!ia.isMulticastAddress()) &&
(!ia.isAnyLocalAddress()) &&
(!ia.isLoopbackAddress()) &&
(!ia.isSiteLocalAddress());
} catch (UnknownHostException uhe) {}
}
}
return false;
}
/**
* Is this a valid port for us or a remote router?
*
* ref: http://i2p-projekt.i2p/en/docs/ports
*
* @since 0.9.17 moved from logic in individual transports
*/
public static boolean isValidPort(int port) {
// update log message in UDPEndpoint if you update this list
return port >= 1024 &&
port <= 65535 &&
port != 1900 && // UPnP SSDP
port != 2827 && // BOB
port != 4444 && // HTTP
port != 4445 && // HTTPS
port != 6668 && // IRC
(!(port >= 7650 && port <= 7664)) && // standard I2P range
port != 8998 && // mtn
port != 31000 && // Wrapper
port != 32000; // Wrapper
}
}