1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.unix;
17
18 import java.net.Inet6Address;
19 import java.net.InetAddress;
20 import java.net.InetSocketAddress;
21 import java.net.UnknownHostException;
22
23
24
25
26 public final class NativeInetAddress {
27 private static final byte[] IPV4_MAPPED_IPV6_PREFIX = {
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xff, (byte) 0xff };
29 final byte[] address;
30 final int scopeId;
31
32 public static NativeInetAddress newInstance(InetAddress addr) {
33 byte[] bytes = addr.getAddress();
34 if (addr instanceof Inet6Address) {
35 return new NativeInetAddress(bytes, ((Inet6Address) addr).getScopeId());
36 } else {
37
38 return new NativeInetAddress(ipv4MappedIpv6Address(bytes));
39 }
40 }
41
42 public NativeInetAddress(byte[] address, int scopeId) {
43 this.address = address;
44 this.scopeId = scopeId;
45 }
46
47 public NativeInetAddress(byte[] address) {
48 this(address, 0);
49 }
50
51 public byte[] address() {
52 return address;
53 }
54
55 public int scopeId() {
56 return scopeId;
57 }
58
59 public static byte[] ipv4MappedIpv6Address(byte[] ipv4) {
60 byte[] address = new byte[16];
61 System.arraycopy(IPV4_MAPPED_IPV6_PREFIX, 0, address, 0, IPV4_MAPPED_IPV6_PREFIX.length);
62 System.arraycopy(ipv4, 0, address, 12, ipv4.length);
63 return address;
64 }
65
66 public static InetSocketAddress address(byte[] addr, int offset, int len) {
67
68 final int port = decodeInt(addr, offset + len - 4);
69 final InetAddress address;
70
71 try {
72 switch (len) {
73
74
75
76 case 8:
77 byte[] ipv4 = new byte[4];
78 System.arraycopy(addr, offset, ipv4, 0, 4);
79 address = InetAddress.getByAddress(ipv4);
80 break;
81
82
83
84
85
86 case 24:
87 byte[] ipv6 = new byte[16];
88 System.arraycopy(addr, offset, ipv6, 0, 16);
89 int scopeId = decodeInt(addr, offset + len - 8);
90 address = Inet6Address.getByAddress(null, ipv6, scopeId);
91 break;
92 default:
93 throw new Error();
94 }
95 return new InetSocketAddress(address, port);
96 } catch (UnknownHostException e) {
97 throw new Error("Should never happen", e);
98 }
99 }
100
101 static int decodeInt(byte[] addr, int index) {
102 return (addr[index] & 0xff) << 24 |
103 (addr[index + 1] & 0xff) << 16 |
104 (addr[index + 2] & 0xff) << 8 |
105 addr[index + 3] & 0xff;
106 }
107 }