protected InetSocketAddress readAddress() throws IOException { // Address int addressType = input.read(); InetAddress address; switch (addressType) { case 1: // IPv4 byte[] ip4 = new byte[4]; readFully(ip4); address = Inet4Address.getByAddress(ip4); break; case 3: // Domain name int size = input.read(); byte[] domain = new byte[size]; readFully(domain); address = InetAddress.getByName(new String(domain, "US-ASCII")); break; case 4: // IPv6 byte[] ip6 = new byte[16]; readFully(ip6); address = Inet6Address.getByAddress(ip6); break; default: throw new SOCKS5Exception( "Unexpected address type in SOCKS server response: " + addressType); } // Port int port = (input.read() << 8) | input.read(); return new InetSocketAddress(address, port); }
@Override protected Inet6Address ipAddressRandomizer(InetAddress realAddress) { byte[] addr = { realAddress.getAddress()[0], realAddress.getAddress()[1], realAddress.getAddress()[2], realAddress.getAddress()[3], realAddress.getAddress()[4], realAddress.getAddress()[5], realAddress.getAddress()[6], realAddress.getAddress()[7], realAddress.getAddress()[8], realAddress.getAddress()[9], realAddress.getAddress()[10], realAddress.getAddress()[11], (byte) 0, (byte) 0, (byte) 0, (byte) 0 }; Inet6Address fakeV4 = null; try { fakeV4 = (Inet6Address) Inet6Address.getByAddress(addr); } catch (UnknownHostException e) { e.printStackTrace(); } return fakeV4; }
public static InetSocketAddress address(byte[] addr, int offset, int len) { // The last 4 bytes are always the port final int port = decodeInt(addr, offset + len - 4); final InetAddress address; try { switch (len) { // 8 bytes: // - 4 == ipaddress // - 4 == port case 8: byte[] ipv4 = new byte[4]; System.arraycopy(addr, offset, ipv4, 0, 4); address = InetAddress.getByAddress(ipv4); break; // 24 bytes: // - 16 == ipaddress // - 4 == scopeId // - 4 == port case 24: byte[] ipv6 = new byte[16]; System.arraycopy(addr, offset, ipv6, 0, 16); int scopeId = decodeInt(addr, offset + len - 8); address = Inet6Address.getByAddress(null, ipv6, scopeId); break; default: throw new Error(); } return new InetSocketAddress(address, port); } catch (UnknownHostException e) { throw new Error("Should never happen", e); } }
@Nonnull public InetAddress getIp() { ByteBuffer buf = ByteBuffer.wrap(getData()); final byte[] dst = new byte[16]; buf.get(dst, 0, 16); try { return Inet6Address.getByAddress(dst); } catch (UnknownHostException e) { // This can happen only if the IP byte array is of illegal length throw new IllegalStateException("Illegal IP address", e); } }
public InetSocketAddress getLocalAddress() throws IOException { if (!nfd.isValid()) return null; ByteBuffer name = ByteBuffer.allocateDirect(18); int namelen = getsockname(nfd.getNativeFD(), name); if (namelen == 0) // not bound return null; // XXX return some wildcard? if (namelen == 4) { byte[] addr = new byte[4]; name.get(addr); int port = name.getShort() & 0xFFFF; return new InetSocketAddress(Inet4Address.getByAddress(addr), port); } if (namelen == 16) { byte[] addr = new byte[16]; name.get(addr); int port = name.getShort() & 0xFFFF; return new InetSocketAddress(Inet6Address.getByAddress(addr), port); } throw new SocketException("invalid address length"); }
/** * Returns the socket address of the remote peer this channel is connected to, or null if this * channel is not yet connected. * * @return The peer address. * @throws IOException */ public InetSocketAddress getPeerAddress() throws IOException { if (!nfd.isValid()) return null; ByteBuffer name = ByteBuffer.allocateDirect(18); int namelen = getpeername(nfd.getNativeFD(), name); if (namelen == 0) // not connected yet return null; if (namelen == 4) // IPv4 { byte[] addr = new byte[4]; name.get(addr); int port = name.getShort() & 0xFFFF; return new InetSocketAddress(Inet4Address.getByAddress(addr), port); } else if (namelen == 16) // IPv6 { byte[] addr = new byte[16]; name.get(addr); int port = name.getShort() & 0xFFFF; return new InetSocketAddress(Inet6Address.getByAddress(addr), port); } throw new SocketException("invalid address length"); }
/** * Receive a datagram on this channel, returning the host address that sent the datagram. * * @param dst Where to store the datagram. * @return The host address that sent the datagram. * @throws IOException */ public SocketAddress receive(ByteBuffer dst) throws IOException { if (kind != Kind.SOCK_DGRAM) throw new SocketException("not a datagram socket"); ByteBuffer hostPort = ByteBuffer.allocateDirect(18); int hostlen = receive(nfd.getNativeFD(), dst, hostPort); if (hostlen == 0) return null; if (hostlen == 4) // IPv4 { byte[] addr = new byte[4]; hostPort.get(addr); int port = hostPort.getShort() & 0xFFFF; return new InetSocketAddress(Inet4Address.getByAddress(addr), port); } if (hostlen == 16) // IPv6 { byte[] addr = new byte[16]; hostPort.get(addr); int port = hostPort.getShort() & 0xFFFF; return new InetSocketAddress(Inet6Address.getByAddress(addr), port); } throw new SocketException("host address received with invalid length: " + hostlen); }