Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/net/Inet6Address.java
41152 views
1
/*
2
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.net;
27
28
import java.io.IOException;
29
import java.io.InvalidObjectException;
30
import java.io.ObjectInputStream;
31
import java.io.ObjectOutputStream;
32
import java.io.ObjectStreamField;
33
import java.util.Enumeration;
34
import java.util.Arrays;
35
36
/**
37
* This class represents an Internet Protocol version 6 (IPv6) address.
38
* Defined by <a href="http://www.ietf.org/rfc/rfc2373.txt">
39
* <i>RFC&nbsp;2373: IP Version 6 Addressing Architecture</i></a>.
40
*
41
* <h2> <a id="format">Textual representation of IP addresses</a> </h2>
42
*
43
* Textual representation of IPv6 address used as input to methods
44
* takes one of the following forms:
45
*
46
* <ol>
47
* <li><p> <a id="lform">The preferred form</a> is x:x:x:x:x:x:x:x,
48
* where the 'x's are
49
* the hexadecimal values of the eight 16-bit pieces of the
50
* address. This is the full form. For example,
51
*
52
* <blockquote><ul style="list-style-type:none">
53
* <li>{@code 1080:0:0:0:8:800:200C:417A}</li>
54
* </ul></blockquote>
55
*
56
* <p> Note that it is not necessary to write the leading zeros in
57
* an individual field. However, there must be at least one numeral
58
* in every field, except as described below.</li>
59
*
60
* <li><p> Due to some methods of allocating certain styles of IPv6
61
* addresses, it will be common for addresses to contain long
62
* strings of zero bits. In order to make writing addresses
63
* containing zero bits easier, a special syntax is available to
64
* compress the zeros. The use of "::" indicates multiple groups
65
* of 16-bits of zeros. The "::" can only appear once in an address.
66
* The "::" can also be used to compress the leading and/or trailing
67
* zeros in an address. For example,
68
*
69
* <blockquote><ul style="list-style-type:none">
70
* <li>{@code 1080::8:800:200C:417A}</li>
71
* </ul></blockquote>
72
*
73
* <li><p> An alternative form that is sometimes more convenient
74
* when dealing with a mixed environment of IPv4 and IPv6 nodes is
75
* x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
76
* of the six high-order 16-bit pieces of the address, and the 'd's
77
* are the decimal values of the four low-order 8-bit pieces of the
78
* standard IPv4 representation address, for example,
79
*
80
* <blockquote><ul style="list-style-type:none">
81
* <li>{@code ::FFFF:129.144.52.38}</li>
82
* <li>{@code ::129.144.52.38}</li>
83
* </ul></blockquote>
84
*
85
* <p> where "::FFFF:d.d.d.d" and "::d.d.d.d" are, respectively, the
86
* general forms of an IPv4-mapped IPv6 address and an
87
* IPv4-compatible IPv6 address. Note that the IPv4 portion must be
88
* in the "d.d.d.d" form. The following forms are invalid:
89
*
90
* <blockquote><ul style="list-style-type:none">
91
* <li>{@code ::FFFF:d.d.d}</li>
92
* <li>{@code ::FFFF:d.d}</li>
93
* <li>{@code ::d.d.d}</li>
94
* <li>{@code ::d.d}</li>
95
* </ul></blockquote>
96
*
97
* <p> The following form:
98
*
99
* <blockquote><ul style="list-style-type:none">
100
* <li>{@code ::FFFF:d}</li>
101
* </ul></blockquote>
102
*
103
* <p> is valid, however it is an unconventional representation of
104
* the IPv4-compatible IPv6 address,
105
*
106
* <blockquote><ul style="list-style-type:none">
107
* <li>{@code ::255.255.0.d}</li>
108
* </ul></blockquote>
109
*
110
* <p> while "::d" corresponds to the general IPv6 address
111
* "0:0:0:0:0:0:0:d".</li>
112
* </ol>
113
*
114
* <p> For methods that return a textual representation as output
115
* value, the full form is used. Inet6Address will return the full
116
* form because it is unambiguous when used in combination with other
117
* textual data.
118
*
119
* <h3> Special IPv6 address </h3>
120
*
121
* <blockquote>
122
* <table class="borderless">
123
* <caption style="display:none">Description of IPv4-mapped address</caption>
124
* <tr><th style="vertical-align:top; padding-right:2px"><i>IPv4-mapped address</i></th>
125
* <td>Of the form ::ffff:w.x.y.z, this IPv6 address is used to
126
* represent an IPv4 address. It allows the native program to
127
* use the same address data structure and also the same
128
* socket when communicating with both IPv4 and IPv6 nodes.
129
*
130
* <p>In InetAddress and Inet6Address, it is used for internal
131
* representation; it has no functional role. Java will never
132
* return an IPv4-mapped address. These classes can take an
133
* IPv4-mapped address as input, both in byte array and text
134
* representation. However, it will be converted into an IPv4
135
* address.</td></tr>
136
* </table></blockquote>
137
*
138
* <h3><a id="scoped">Textual representation of IPv6 scoped addresses</a></h3>
139
*
140
* <p> The textual representation of IPv6 addresses as described above can be
141
* extended to specify IPv6 scoped addresses. This extension to the basic
142
* addressing architecture is described in [draft-ietf-ipngwg-scoping-arch-04.txt].
143
*
144
* <p> Because link-local and site-local addresses are non-global, it is possible
145
* that different hosts may have the same destination address and may be
146
* reachable through different interfaces on the same originating system. In
147
* this case, the originating system is said to be connected to multiple zones
148
* of the same scope. In order to disambiguate which is the intended destination
149
* zone, it is possible to append a zone identifier (or <i>scope_id</i>) to an
150
* IPv6 address.
151
*
152
* <p> The general format for specifying the <i>scope_id</i> is the following:
153
*
154
* <blockquote><i>IPv6-address</i>%<i>scope_id</i></blockquote>
155
* <p> The IPv6-address is a literal IPv6 address as described above.
156
* The <i>scope_id</i> refers to an interface on the local system, and it can be
157
* specified in two ways.
158
* <ol><li><i>As a numeric identifier.</i> This must be a positive integer
159
* that identifies the particular interface and scope as understood by the
160
* system. Usually, the numeric values can be determined through administration
161
* tools on the system. Each interface may have multiple values, one for each
162
* scope. If the scope is unspecified, then the default value used is zero.</li>
163
* <li><i>As a string.</i> This must be the exact string that is returned by
164
* {@link java.net.NetworkInterface#getName()} for the particular interface in
165
* question. When an Inet6Address is created in this way, the numeric scope-id
166
* is determined at the time the object is created by querying the relevant
167
* NetworkInterface.</li></ol>
168
*
169
* <p> Note also, that the numeric <i>scope_id</i> can be retrieved from
170
* Inet6Address instances returned from the NetworkInterface class. This can be
171
* used to find out the current scope ids configured on the system.
172
* @since 1.4
173
*/
174
175
public final
176
class Inet6Address extends InetAddress {
177
static final int INADDRSZ = 16;
178
179
private static class Inet6AddressHolder {
180
181
private Inet6AddressHolder() {
182
ipaddress = new byte[INADDRSZ];
183
}
184
185
private Inet6AddressHolder(
186
byte[] ipaddress, int scope_id, boolean scope_id_set,
187
NetworkInterface ifname, boolean scope_ifname_set)
188
{
189
this.ipaddress = ipaddress;
190
this.scope_id = scope_id;
191
this.scope_id_set = scope_id_set;
192
this.scope_ifname_set = scope_ifname_set;
193
this.scope_ifname = ifname;
194
}
195
196
/**
197
* Holds a 128-bit (16 bytes) IPv6 address.
198
*/
199
byte[] ipaddress;
200
201
/**
202
* scope_id. The scope specified when the object is created. If the object
203
* is created with an interface name, then the scope_id is not determined
204
* until the time it is needed.
205
*/
206
int scope_id; // 0
207
208
/**
209
* This will be set to true when the scope_id field contains a valid
210
* integer scope_id.
211
*/
212
boolean scope_id_set; // false
213
214
/**
215
* scoped interface. scope_id is derived from this as the scope_id of the first
216
* address whose scope is the same as this address for the named interface.
217
*/
218
NetworkInterface scope_ifname; // null
219
220
/**
221
* set if the object is constructed with a scoped
222
* interface instead of a numeric scope id.
223
*/
224
boolean scope_ifname_set; // false;
225
226
void setAddr(byte addr[]) {
227
if (addr.length == INADDRSZ) { // normal IPv6 address
228
System.arraycopy(addr, 0, ipaddress, 0, INADDRSZ);
229
}
230
}
231
232
void init(byte addr[], int scope_id) {
233
setAddr(addr);
234
235
if (scope_id >= 0) {
236
this.scope_id = scope_id;
237
this.scope_id_set = true;
238
}
239
}
240
241
void init(byte addr[], NetworkInterface nif)
242
throws UnknownHostException
243
{
244
setAddr(addr);
245
246
if (nif != null) {
247
this.scope_id = deriveNumericScope(ipaddress, nif);
248
this.scope_id_set = true;
249
this.scope_ifname = nif;
250
this.scope_ifname_set = true;
251
}
252
}
253
254
String getHostAddress() {
255
String s = numericToTextFormat(ipaddress);
256
if (scope_ifname != null) { /* must check this first */
257
s = s + "%" + scope_ifname.getName();
258
} else if (scope_id_set) {
259
s = s + "%" + scope_id;
260
}
261
return s;
262
}
263
264
public boolean equals(Object o) {
265
if (!(o instanceof Inet6AddressHolder that)) {
266
return false;
267
}
268
269
return Arrays.equals(this.ipaddress, that.ipaddress);
270
}
271
272
public int hashCode() {
273
if (ipaddress != null) {
274
275
int hash = 0;
276
int i=0;
277
while (i<INADDRSZ) {
278
int j=0;
279
int component=0;
280
while (j<4 && i<INADDRSZ) {
281
component = (component << 8) + ipaddress[i];
282
j++;
283
i++;
284
}
285
hash += component;
286
}
287
return hash;
288
289
} else {
290
return 0;
291
}
292
}
293
294
boolean isIPv4CompatibleAddress() {
295
if ((ipaddress[0] == 0x00) && (ipaddress[1] == 0x00) &&
296
(ipaddress[2] == 0x00) && (ipaddress[3] == 0x00) &&
297
(ipaddress[4] == 0x00) && (ipaddress[5] == 0x00) &&
298
(ipaddress[6] == 0x00) && (ipaddress[7] == 0x00) &&
299
(ipaddress[8] == 0x00) && (ipaddress[9] == 0x00) &&
300
(ipaddress[10] == 0x00) && (ipaddress[11] == 0x00)) {
301
return true;
302
}
303
return false;
304
}
305
306
boolean isMulticastAddress() {
307
return ((ipaddress[0] & 0xff) == 0xff);
308
}
309
310
boolean isAnyLocalAddress() {
311
byte test = 0x00;
312
for (int i = 0; i < INADDRSZ; i++) {
313
test |= ipaddress[i];
314
}
315
return (test == 0x00);
316
}
317
318
boolean isLoopbackAddress() {
319
byte test = 0x00;
320
for (int i = 0; i < 15; i++) {
321
test |= ipaddress[i];
322
}
323
return (test == 0x00) && (ipaddress[15] == 0x01);
324
}
325
326
boolean isLinkLocalAddress() {
327
return ((ipaddress[0] & 0xff) == 0xfe
328
&& (ipaddress[1] & 0xc0) == 0x80);
329
}
330
331
332
boolean isSiteLocalAddress() {
333
return ((ipaddress[0] & 0xff) == 0xfe
334
&& (ipaddress[1] & 0xc0) == 0xc0);
335
}
336
337
boolean isMCGlobal() {
338
return ((ipaddress[0] & 0xff) == 0xff
339
&& (ipaddress[1] & 0x0f) == 0x0e);
340
}
341
342
boolean isMCNodeLocal() {
343
return ((ipaddress[0] & 0xff) == 0xff
344
&& (ipaddress[1] & 0x0f) == 0x01);
345
}
346
347
boolean isMCLinkLocal() {
348
return ((ipaddress[0] & 0xff) == 0xff
349
&& (ipaddress[1] & 0x0f) == 0x02);
350
}
351
352
boolean isMCSiteLocal() {
353
return ((ipaddress[0] & 0xff) == 0xff
354
&& (ipaddress[1] & 0x0f) == 0x05);
355
}
356
357
boolean isMCOrgLocal() {
358
return ((ipaddress[0] & 0xff) == 0xff
359
&& (ipaddress[1] & 0x0f) == 0x08);
360
}
361
}
362
363
private final transient Inet6AddressHolder holder6;
364
365
@java.io.Serial
366
private static final long serialVersionUID = 6880410070516793377L;
367
368
// Perform native initialization
369
static { init(); }
370
371
Inet6Address() {
372
super();
373
holder.init(null, IPv6);
374
holder6 = new Inet6AddressHolder();
375
}
376
377
/* checking of value for scope_id should be done by caller
378
* scope_id must be >= 0, or -1 to indicate not being set
379
*/
380
Inet6Address(String hostName, byte addr[], int scope_id) {
381
holder.init(hostName, IPv6);
382
holder6 = new Inet6AddressHolder();
383
holder6.init(addr, scope_id);
384
}
385
386
Inet6Address(String hostName, byte addr[]) {
387
holder6 = new Inet6AddressHolder();
388
try {
389
initif (hostName, addr, null);
390
} catch (UnknownHostException e) {} /* cant happen if ifname is null */
391
}
392
393
Inet6Address (String hostName, byte addr[], NetworkInterface nif)
394
throws UnknownHostException
395
{
396
holder6 = new Inet6AddressHolder();
397
initif (hostName, addr, nif);
398
}
399
400
Inet6Address (String hostName, byte addr[], String ifname)
401
throws UnknownHostException
402
{
403
holder6 = new Inet6AddressHolder();
404
initstr (hostName, addr, ifname);
405
}
406
407
/**
408
* Create an Inet6Address in the exact manner of {@link
409
* InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is
410
* set to the value corresponding to the given interface for the address
411
* type specified in {@code addr}. The call will fail with an
412
* UnknownHostException if the given interface does not have a numeric
413
* scope_id assigned for the given address type (e.g. link-local or site-local).
414
* See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
415
* scoped addresses.
416
*
417
* @param host the specified host
418
* @param addr the raw IP address in network byte order
419
* @param nif an interface this address must be associated with.
420
* @return an Inet6Address object created from the raw IP address.
421
* @throws UnknownHostException
422
* if IP address is of illegal length, or if the interface does not
423
* have a numeric scope_id assigned for the given address type.
424
*
425
* @since 1.5
426
*/
427
public static Inet6Address getByAddress(String host, byte[] addr,
428
NetworkInterface nif)
429
throws UnknownHostException
430
{
431
if (host != null && !host.isEmpty() && host.charAt(0) == '[') {
432
if (host.charAt(host.length()-1) == ']') {
433
host = host.substring(1, host.length() -1);
434
}
435
}
436
if (addr != null) {
437
if (addr.length == Inet6Address.INADDRSZ) {
438
return new Inet6Address(host, addr, nif);
439
}
440
}
441
throw new UnknownHostException("addr is of illegal length");
442
}
443
444
/**
445
* Create an Inet6Address in the exact manner of {@link
446
* InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is
447
* set to the given numeric value. The scope_id is not checked to determine
448
* if it corresponds to any interface on the system.
449
* See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
450
* scoped addresses.
451
*
452
* @param host the specified host
453
* @param addr the raw IP address in network byte order
454
* @param scope_id the numeric scope_id for the address.
455
* @return an Inet6Address object created from the raw IP address.
456
* @throws UnknownHostException if IP address is of illegal length.
457
*
458
* @since 1.5
459
*/
460
public static Inet6Address getByAddress(String host, byte[] addr,
461
int scope_id)
462
throws UnknownHostException
463
{
464
if (host != null && !host.isEmpty() && host.charAt(0) == '[') {
465
if (host.charAt(host.length()-1) == ']') {
466
host = host.substring(1, host.length() -1);
467
}
468
}
469
if (addr != null) {
470
if (addr.length == Inet6Address.INADDRSZ) {
471
return new Inet6Address(host, addr, scope_id);
472
}
473
}
474
throw new UnknownHostException("addr is of illegal length");
475
}
476
477
private void initstr(String hostName, byte addr[], String ifname)
478
throws UnknownHostException
479
{
480
try {
481
NetworkInterface nif = NetworkInterface.getByName (ifname);
482
if (nif == null) {
483
throw new UnknownHostException ("no such interface " + ifname);
484
}
485
initif (hostName, addr, nif);
486
} catch (SocketException e) {
487
throw new UnknownHostException ("SocketException thrown" + ifname);
488
}
489
}
490
491
private void initif(String hostName, byte addr[], NetworkInterface nif)
492
throws UnknownHostException
493
{
494
int family = -1;
495
holder6.init(addr, nif);
496
497
if (addr.length == INADDRSZ) { // normal IPv6 address
498
family = IPv6;
499
}
500
holder.init(hostName, family);
501
}
502
503
/* check the two Ipv6 addresses and return false if they are both
504
* non global address types, but not the same.
505
* (i.e. one is site-local and the other link-local)
506
* return true otherwise.
507
*/
508
509
private static boolean isDifferentLocalAddressType(
510
byte[] thisAddr, byte[] otherAddr) {
511
512
if (Inet6Address.isLinkLocalAddress(thisAddr) &&
513
!Inet6Address.isLinkLocalAddress(otherAddr)) {
514
return false;
515
}
516
if (Inet6Address.isSiteLocalAddress(thisAddr) &&
517
!Inet6Address.isSiteLocalAddress(otherAddr)) {
518
return false;
519
}
520
return true;
521
}
522
523
private static int deriveNumericScope (byte[] thisAddr, NetworkInterface ifc) throws UnknownHostException {
524
Enumeration<InetAddress> addresses = ifc.getInetAddresses();
525
while (addresses.hasMoreElements()) {
526
InetAddress addr = addresses.nextElement();
527
if (!(addr instanceof Inet6Address ia6_addr)) {
528
continue;
529
}
530
/* check if site or link local prefixes match */
531
if (!isDifferentLocalAddressType(thisAddr, ia6_addr.getAddress())){
532
/* type not the same, so carry on searching */
533
continue;
534
}
535
/* found a matching address - return its scope_id */
536
return ia6_addr.getScopeId();
537
}
538
throw new UnknownHostException ("no scope_id found");
539
}
540
541
private int deriveNumericScope (String ifname) throws UnknownHostException {
542
Enumeration<NetworkInterface> en;
543
try {
544
en = NetworkInterface.getNetworkInterfaces();
545
} catch (SocketException e) {
546
throw new UnknownHostException ("could not enumerate local network interfaces");
547
}
548
while (en.hasMoreElements()) {
549
NetworkInterface ifc = en.nextElement();
550
if (ifc.getName().equals (ifname)) {
551
return deriveNumericScope(holder6.ipaddress, ifc);
552
}
553
}
554
throw new UnknownHostException ("No matching address found for interface : " +ifname);
555
}
556
557
/**
558
* @serialField ipaddress byte[] holds a 128-bit (16 bytes) IPv6 address
559
* @serialField scope_id int the address scope id. {@code 0} if undefined
560
* @serialField scope_id_set boolean {@code true} when the scope_id field
561
* contains a valid integer scope_id
562
* @serialField scope_ifname_set boolean {@code true} if the object is
563
* constructed with a scoped interface instead of a numeric
564
* scope id
565
* @serialField ifname String the name of the scoped network interface.
566
* {@code null} if undefined
567
*/
568
@java.io.Serial
569
private static final ObjectStreamField[] serialPersistentFields = {
570
new ObjectStreamField("ipaddress", byte[].class),
571
new ObjectStreamField("scope_id", int.class),
572
new ObjectStreamField("scope_id_set", boolean.class),
573
new ObjectStreamField("scope_ifname_set", boolean.class),
574
new ObjectStreamField("ifname", String.class)
575
};
576
577
private static final jdk.internal.misc.Unsafe UNSAFE
578
= jdk.internal.misc.Unsafe.getUnsafe();
579
private static final long FIELDS_OFFSET = UNSAFE.objectFieldOffset(
580
Inet6Address.class, "holder6");
581
582
/**
583
* Restores the state of this object from the stream.
584
* This includes the scope information, but only if the
585
* scoped interface name is valid on this system.
586
*
587
* @param s the {@code ObjectInputStream} from which data is read
588
* @throws IOException if an I/O error occurs
589
* @throws ClassNotFoundException if a serialized class cannot be loaded
590
*/
591
@java.io.Serial
592
private void readObject(ObjectInputStream s)
593
throws IOException, ClassNotFoundException {
594
NetworkInterface scope_ifname = null;
595
596
if (getClass().getClassLoader() != null) {
597
throw new SecurityException ("invalid address type");
598
}
599
600
ObjectInputStream.GetField gf = s.readFields();
601
byte[] ipaddress = (byte[])gf.get("ipaddress", new byte[0]);
602
int scope_id = gf.get("scope_id", -1);
603
boolean scope_id_set = gf.get("scope_id_set", false);
604
boolean scope_ifname_set = gf.get("scope_ifname_set", false);
605
String ifname = (String)gf.get("ifname", null);
606
607
if (ifname != null && !ifname.isEmpty()) {
608
try {
609
scope_ifname = NetworkInterface.getByName(ifname);
610
if (scope_ifname == null) {
611
/* the interface does not exist on this system, so we clear
612
* the scope information completely */
613
scope_id_set = false;
614
scope_ifname_set = false;
615
scope_id = 0;
616
} else {
617
scope_ifname_set = true;
618
try {
619
scope_id = deriveNumericScope (ipaddress, scope_ifname);
620
} catch (UnknownHostException e) {
621
// typically should not happen, but it may be that
622
// the machine being used for deserialization has
623
// the same interface name but without IPv6 configured.
624
}
625
}
626
} catch (SocketException e) {}
627
}
628
629
/* if ifname was not supplied, then the numeric info is used */
630
631
ipaddress = ipaddress.clone();
632
633
// Check that our invariants are satisfied
634
if (ipaddress.length != INADDRSZ) {
635
throw new InvalidObjectException("invalid address length: "+
636
ipaddress.length);
637
}
638
639
if (holder.getFamily() != IPv6) {
640
throw new InvalidObjectException("invalid address family type");
641
}
642
643
Inet6AddressHolder h = new Inet6AddressHolder(
644
ipaddress, scope_id, scope_id_set, scope_ifname, scope_ifname_set
645
);
646
647
UNSAFE.putReference(this, FIELDS_OFFSET, h);
648
}
649
650
/**
651
* The default behavior of this method is overridden in order to
652
* write the scope_ifname field as a {@code String}, rather than a
653
* {@code NetworkInterface} which is not serializable.
654
*
655
* @param s the {@code ObjectOutputStream} to which data is written
656
* @throws IOException if an I/O error occurs
657
*/
658
@java.io.Serial
659
private synchronized void writeObject(ObjectOutputStream s)
660
throws IOException
661
{
662
String ifname = null;
663
664
if (holder6.scope_ifname != null) {
665
ifname = holder6.scope_ifname.getName();
666
holder6.scope_ifname_set = true;
667
}
668
ObjectOutputStream.PutField pfields = s.putFields();
669
pfields.put("ipaddress", holder6.ipaddress);
670
pfields.put("scope_id", holder6.scope_id);
671
pfields.put("scope_id_set", holder6.scope_id_set);
672
pfields.put("scope_ifname_set", holder6.scope_ifname_set);
673
pfields.put("ifname", ifname);
674
s.writeFields();
675
}
676
677
/**
678
* Utility routine to check if the InetAddress is an IP multicast
679
* address. 11111111 at the start of the address identifies the
680
* address as being a multicast address.
681
*
682
* @return a {@code boolean} indicating if the InetAddress is an IP
683
* multicast address
684
*/
685
@Override
686
public boolean isMulticastAddress() {
687
return holder6.isMulticastAddress();
688
}
689
690
/**
691
* Utility routine to check if the InetAddress is a wildcard address.
692
*
693
* @return a {@code boolean} indicating if the InetAddress is
694
* a wildcard address.
695
*/
696
@Override
697
public boolean isAnyLocalAddress() {
698
return holder6.isAnyLocalAddress();
699
}
700
701
/**
702
* Utility routine to check if the InetAddress is a loopback address.
703
*
704
* @return a {@code boolean} indicating if the InetAddress is a loopback
705
* address; or false otherwise.
706
*/
707
@Override
708
public boolean isLoopbackAddress() {
709
return holder6.isLoopbackAddress();
710
}
711
712
/**
713
* Utility routine to check if the InetAddress is an link local address.
714
*
715
* @return a {@code boolean} indicating if the InetAddress is a link local
716
* address; or false if address is not a link local unicast address.
717
*/
718
@Override
719
public boolean isLinkLocalAddress() {
720
return holder6.isLinkLocalAddress();
721
}
722
723
/* static version of above */
724
static boolean isLinkLocalAddress(byte[] ipaddress) {
725
return ((ipaddress[0] & 0xff) == 0xfe
726
&& (ipaddress[1] & 0xc0) == 0x80);
727
}
728
729
/**
730
* Utility routine to check if the InetAddress is a site local address.
731
*
732
* @return a {@code boolean} indicating if the InetAddress is a site local
733
* address; or false if address is not a site local unicast address.
734
*/
735
@Override
736
public boolean isSiteLocalAddress() {
737
return holder6.isSiteLocalAddress();
738
}
739
740
/* static version of above */
741
static boolean isSiteLocalAddress(byte[] ipaddress) {
742
return ((ipaddress[0] & 0xff) == 0xfe
743
&& (ipaddress[1] & 0xc0) == 0xc0);
744
}
745
746
/**
747
* Utility routine to check if the multicast address has global scope.
748
*
749
* @return a {@code boolean} indicating if the address has is a multicast
750
* address of global scope, false if it is not of global scope or
751
* it is not a multicast address
752
*/
753
@Override
754
public boolean isMCGlobal() {
755
return holder6.isMCGlobal();
756
}
757
758
/**
759
* Utility routine to check if the multicast address has node scope.
760
*
761
* @return a {@code boolean} indicating if the address has is a multicast
762
* address of node-local scope, false if it is not of node-local
763
* scope or it is not a multicast address
764
*/
765
@Override
766
public boolean isMCNodeLocal() {
767
return holder6.isMCNodeLocal();
768
}
769
770
/**
771
* Utility routine to check if the multicast address has link scope.
772
*
773
* @return a {@code boolean} indicating if the address has is a multicast
774
* address of link-local scope, false if it is not of link-local
775
* scope or it is not a multicast address
776
*/
777
@Override
778
public boolean isMCLinkLocal() {
779
return holder6.isMCLinkLocal();
780
}
781
782
/**
783
* Utility routine to check if the multicast address has site scope.
784
*
785
* @return a {@code boolean} indicating if the address has is a multicast
786
* address of site-local scope, false if it is not of site-local
787
* scope or it is not a multicast address
788
*/
789
@Override
790
public boolean isMCSiteLocal() {
791
return holder6.isMCSiteLocal();
792
}
793
794
/**
795
* Utility routine to check if the multicast address has organization scope.
796
*
797
* @return a {@code boolean} indicating if the address has is a multicast
798
* address of organization-local scope, false if it is not of
799
* organization-local scope or it is not a multicast address
800
*/
801
@Override
802
public boolean isMCOrgLocal() {
803
return holder6.isMCOrgLocal();
804
}
805
806
/**
807
* Returns the raw IP address of this {@code InetAddress} object. The result
808
* is in network byte order: the highest order byte of the address is in
809
* {@code getAddress()[0]}.
810
*
811
* @return the raw IP address of this object.
812
*/
813
@Override
814
public byte[] getAddress() {
815
return holder6.ipaddress.clone();
816
}
817
818
/**
819
* Returns a reference to the byte[] with the IPv6 address.
820
*/
821
byte[] addressBytes() {
822
return holder6.ipaddress;
823
}
824
825
/**
826
* Returns the numeric scopeId, if this instance is associated with
827
* an interface. If no scoped_id is set, the returned value is zero.
828
*
829
* @return the scopeId, or zero if not set.
830
*
831
* @since 1.5
832
*/
833
public int getScopeId() {
834
return holder6.scope_id;
835
}
836
837
/**
838
* Returns the scoped interface, if this instance was created with
839
* a scoped interface.
840
*
841
* @return the scoped interface, or null if not set.
842
* @since 1.5
843
*/
844
public NetworkInterface getScopedInterface() {
845
return holder6.scope_ifname;
846
}
847
848
/**
849
* Returns the IP address string in textual presentation. If the instance
850
* was created specifying a scope identifier then the scope id is appended
851
* to the IP address preceded by a "%" (per-cent) character. This can be
852
* either a numeric value or a string, depending on which was used to create
853
* the instance.
854
*
855
* @return the raw IP address in a string format.
856
*/
857
@Override
858
public String getHostAddress() {
859
return holder6.getHostAddress();
860
}
861
862
/**
863
* Returns a hashcode for this IP address.
864
*
865
* @return a hash code value for this IP address.
866
*/
867
@Override
868
public int hashCode() {
869
return holder6.hashCode();
870
}
871
872
/**
873
* Compares this object against the specified object. The result is {@code
874
* true} if and only if the argument is not {@code null} and it represents
875
* the same IP address as this object.
876
*
877
* <p> Two instances of {@code InetAddress} represent the same IP address
878
* if the length of the byte arrays returned by {@code getAddress} is the
879
* same for both, and each of the array components is the same for the byte
880
* arrays.
881
*
882
* @param obj the object to compare against.
883
*
884
* @return {@code true} if the objects are the same; {@code false} otherwise.
885
*
886
* @see java.net.InetAddress#getAddress()
887
*/
888
@Override
889
public boolean equals(Object obj) {
890
if (obj instanceof Inet6Address inetAddr) {
891
return holder6.equals(inetAddr.holder6);
892
}
893
return false;
894
}
895
896
/**
897
* Utility routine to check if the InetAddress is an
898
* IPv4 compatible IPv6 address.
899
*
900
* @return a {@code boolean} indicating if the InetAddress is an IPv4
901
* compatible IPv6 address; or false if address is IPv4 address.
902
*/
903
public boolean isIPv4CompatibleAddress() {
904
return holder6.isIPv4CompatibleAddress();
905
}
906
907
// Utilities
908
909
private static final int INT16SZ = 2;
910
911
/**
912
* Convert IPv6 binary address into presentation (printable) format.
913
*
914
* @param src a byte array representing the IPv6 numeric address
915
* @return a String representing an IPv6 address in
916
* textual representation format
917
*/
918
static String numericToTextFormat(byte[] src) {
919
StringBuilder sb = new StringBuilder(39);
920
for (int i = 0; i < (INADDRSZ / INT16SZ); i++) {
921
sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00)
922
| (src[(i<<1)+1] & 0xff)));
923
if (i < (INADDRSZ / INT16SZ) -1 ) {
924
sb.append(":");
925
}
926
}
927
return sb.toString();
928
}
929
930
/**
931
* Perform class load-time initializations.
932
*/
933
private static native void init();
934
}
935
936