1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.net;
19
20import java.io.ObjectStreamException;
21import java.nio.ByteOrder;
22import libcore.io.Memory;
23import static android.system.OsConstants.*;
24
25/**
26 * An IPv4 address. See {@link InetAddress}.
27 */
28public final class Inet4Address extends InetAddress {
29
30    private static final long serialVersionUID = 3286316764910316507L;
31
32    /**
33     * @hide
34     */
35    public static final InetAddress ANY =
36            new Inet4Address(new byte[] { 0, 0, 0, 0 }, null);
37
38    /**
39     * @hide
40     */
41    public static final InetAddress ALL =
42            new Inet4Address(new byte[] { (byte) 255, (byte) 255,
43                                          (byte) 255, (byte) 255 }, null);
44
45    /**
46     * @hide
47     */
48    public static final InetAddress LOOPBACK =
49            new Inet4Address(new byte[] { 127, 0, 0, 1 }, "localhost");
50
51    Inet4Address(byte[] ipaddress, String hostName) {
52        super(AF_INET, ipaddress, hostName);
53    }
54
55    @Override public boolean isAnyLocalAddress() {
56        return ipaddress[0] == 0 && ipaddress[1] == 0 && ipaddress[2] == 0 && ipaddress[3] == 0; // 0.0.0.0
57    }
58
59    @Override public boolean isLinkLocalAddress() {
60        // The RI does not return true for loopback addresses even though RFC 3484 says to do so.
61        return ((ipaddress[0] & 0xff) == 169) && ((ipaddress[1] & 0xff) == 254); // 169.254/16
62    }
63
64    @Override public boolean isLoopbackAddress() {
65        return ((ipaddress[0] & 0xff) == 127); // 127/8
66    }
67
68    @Override public boolean isMCGlobal() {
69        // Check if we have a prefix of 1110
70        if (!isMulticastAddress()) {
71            return false;
72        }
73
74        int address = Memory.peekInt(ipaddress, 0, ByteOrder.BIG_ENDIAN);
75        /*
76         * Now check the boundaries of the global space if we have an address
77         * that is prefixed by something less than 111000000000000000000001
78         * (fortunately we don't have to worry about sign after shifting 8 bits
79         * right) it is not multicast. ( < 224.0.1.0)
80         */
81        if (address >>> 8 < 0xE00001) {
82            return false;
83        }
84
85        /*
86         * Now check the high boundary which is prefixed by 11101110 = 0xEE. If
87         * the value is higher than this than it is not MCGlobal ( >
88         * 238.255.255.255 )
89         */
90        if (address >>> 24 > 0xEE) {
91            return false;
92        }
93
94        return true;
95    }
96
97    @Override public boolean isMCLinkLocal() {
98        return ((ipaddress[0] & 0xff) == 224) && (ipaddress[1] == 0) && (ipaddress[2] == 0); // 224.0.0/24
99    }
100
101    @Override public boolean isMCNodeLocal() {
102        return false;
103    }
104
105    @Override public boolean isMCOrgLocal() {
106        return ((ipaddress[0] & 0xff) == 239) && ((ipaddress[1] & 0xfc) == 192); // 239.192/14
107    }
108
109    @Override public boolean isMCSiteLocal() {
110        return ((ipaddress[0] & 0xff) == 239) && ((ipaddress[1] & 0xff) == 255); // 239.255/16
111    }
112
113    @Override public boolean isMulticastAddress() {
114        return (ipaddress[0] & 0xf0) == 224; // 224/4
115    }
116
117    @Override public boolean isSiteLocalAddress() {
118        if ((ipaddress[0] & 0xff) == 10) { // 10/8
119            return true;
120        } else if (((ipaddress[0] & 0xff) == 172) && ((ipaddress[1] & 0xf0) == 16)) { // 172.16/12
121            return true;
122        } else if (((ipaddress[0] & 0xff) == 192) && ((ipaddress[1] & 0xff) == 168)) { // 192.168/16
123            return true;
124        }
125        return false;
126    }
127
128    private Object writeReplace() throws ObjectStreamException {
129        return new Inet4Address(ipaddress, hostName);
130    }
131}
132