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 copyIpv4MappedIpv6Address(ipv4, address);
62 return address;
63 }
64
65 public static void copyIpv4MappedIpv6Address(byte[] ipv4, byte[] ipv6) {
66 System.arraycopy(IPV4_MAPPED_IPV6_PREFIX, 0, ipv6, 0, IPV4_MAPPED_IPV6_PREFIX.length);
67 System.arraycopy(ipv4, 0, ipv6, 12, ipv4.length);
68 }
69
70 public static InetSocketAddress address(byte[] addr, int offset, int len) {
71
72 final int port = decodeInt(addr, offset + len - 4);
73 final InetAddress address;
74 try {
75 switch (len) {
76
77
78
79 case 8:
80 byte[] ipv4 = new byte[4];
81 System.arraycopy(addr, offset, ipv4, 0, 4);
82 address = InetAddress.getByAddress(ipv4);
83 break;
84
85
86
87
88
89 case 24:
90 byte[] ipv6 = new byte[16];
91 System.arraycopy(addr, offset, ipv6, 0, 16);
92 int scopeId = decodeInt(addr, offset + len - 8);
93
94
95
96 if (scopeId != 0 || (ipv6[0] == (byte) 0xfe && ipv6[1] == (byte) 0x80)) {
97 address = Inet6Address.getByAddress(null, ipv6, scopeId);
98 } else {
99 address = InetAddress.getByAddress(null, ipv6);
100 }
101 break;
102 default:
103 throw new Error();
104 }
105 return new InetSocketAddress(address, port);
106 } catch (UnknownHostException e) {
107 throw new Error("Should never happen", e);
108 }
109 }
110
111 static int decodeInt(byte[] addr, int index) {
112 return (addr[index] & 0xff) << 24 |
113 (addr[index + 1] & 0xff) << 16 |
114 (addr[index + 2] & 0xff) << 8 |
115 addr[index + 3] & 0xff;
116 }
117 }