Merge "Improve code style in Struct.java and add tests for Type.U64 represented by long primitive."
diff --git a/staticlibs/device/com/android/net/module/util/NetworkStackConstants.java b/staticlibs/device/com/android/net/module/util/NetworkStackConstants.java
new file mode 100644
index 0000000..1088477
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/NetworkStackConstants.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Network constants used by the network stack.
+ */
+public final class NetworkStackConstants {
+
+    /**
+     * Ethernet constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc894
+     *     - https://tools.ietf.org/html/rfc2464
+     *     - https://tools.ietf.org/html/rfc7042
+     *     - http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
+     *     - http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
+     */
+    public static final int ETHER_DST_ADDR_OFFSET = 0;
+    public static final int ETHER_SRC_ADDR_OFFSET = 6;
+    public static final int ETHER_ADDR_LEN = 6;
+    public static final int ETHER_TYPE_OFFSET = 12;
+    public static final int ETHER_TYPE_LENGTH = 2;
+    public static final int ETHER_TYPE_ARP  = 0x0806;
+    public static final int ETHER_TYPE_IPV4 = 0x0800;
+    public static final int ETHER_TYPE_IPV6 = 0x86dd;
+    public static final int ETHER_HEADER_LEN = 14;
+    public static final int ETHER_MTU = 1500;
+
+    /**
+     * ARP constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc826
+     *     - http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
+     */
+    public static final int ARP_PAYLOAD_LEN = 28;  // For Ethernet+IPv4.
+    public static final int ARP_ETHER_IPV4_LEN = ARP_PAYLOAD_LEN + ETHER_HEADER_LEN;
+    public static final int ARP_REQUEST = 1;
+    public static final int ARP_REPLY   = 2;
+    public static final int ARP_HWTYPE_RESERVED_LO = 0;
+    public static final int ARP_HWTYPE_ETHER       = 1;
+    public static final int ARP_HWTYPE_RESERVED_HI = 0xffff;
+
+    /**
+     * IPv4 Address Conflict Detection constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc5227
+     */
+    public static final int IPV4_CONFLICT_PROBE_NUM = 3;
+    public static final int IPV4_CONFLICT_ANNOUNCE_NUM = 2;
+
+    /**
+     * IPv4 constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc791
+     */
+    public static final int IPV4_ADDR_BITS = 32;
+    public static final int IPV4_MIN_MTU = 68;
+    public static final int IPV4_MAX_MTU = 65_535;
+    public static final int IPV4_HEADER_MIN_LEN = 20;
+    public static final int IPV4_IHL_MASK = 0xf;
+    public static final int IPV4_FLAGS_OFFSET = 6;
+    public static final int IPV4_FRAGMENT_MASK = 0x1fff;
+    public static final int IPV4_PROTOCOL_OFFSET = 9;
+    public static final int IPV4_SRC_ADDR_OFFSET = 12;
+    public static final int IPV4_DST_ADDR_OFFSET = 16;
+    public static final int IPV4_ADDR_LEN = 4;
+    public static final Inet4Address IPV4_ADDR_ALL = makeInet4Address(
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff);
+    public static final Inet4Address IPV4_ADDR_ANY = makeInet4Address(
+            (byte) 0, (byte) 0, (byte) 0, (byte) 0);
+
+    /**
+     * IPv6 constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc2460
+     */
+    public static final int IPV6_ADDR_LEN = 16;
+    public static final int IPV6_HEADER_LEN = 40;
+    public static final int IPV6_LEN_OFFSET = 4;
+    public static final int IPV6_PROTOCOL_OFFSET = 6;
+    public static final int IPV6_SRC_ADDR_OFFSET = 8;
+    public static final int IPV6_DST_ADDR_OFFSET = 24;
+    public static final int IPV6_MIN_MTU = 1280;
+
+    /**
+     * ICMPv6 constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc4443
+     *     - https://tools.ietf.org/html/rfc4861
+     */
+    public static final int ICMPV6_HEADER_MIN_LEN = 4;
+    public static final int ICMPV6_CHECKSUM_OFFSET = 2;
+    public static final int ICMPV6_ECHO_REPLY_TYPE = 129;
+    public static final int ICMPV6_ECHO_REQUEST_TYPE = 128;
+    public static final int ICMPV6_ROUTER_SOLICITATION    = 133;
+    public static final int ICMPV6_ROUTER_ADVERTISEMENT   = 134;
+    public static final int ICMPV6_NEIGHBOR_SOLICITATION  = 135;
+    public static final int ICMPV6_NEIGHBOR_ADVERTISEMENT = 136;
+    public static final int ICMPV6_ND_OPTION_MIN_LENGTH = 8;
+    public static final int ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR = 8;
+    public static final int ICMPV6_ND_OPTION_SLLA  = 1;
+    public static final int ICMPV6_ND_OPTION_TLLA  = 2;
+    public static final int ICMPV6_ND_OPTION_PIO   = 3;
+    public static final int ICMPV6_ND_OPTION_MTU   = 5;
+    public static final int ICMPV6_ND_OPTION_RDNSS = 25;
+    public static final int ICMPV6_ND_OPTION_PREF64 = 38;
+
+
+    public static final int ICMPV6_RA_HEADER_LEN = 16;
+
+    /**
+     * UDP constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc768
+     */
+    public static final int UDP_HEADER_LEN = 8;
+
+
+    /**
+     * DHCP constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc2131
+     */
+    public static final int INFINITE_LEASE = 0xffffffff;
+    public static final int DHCP4_CLIENT_PORT = 68;
+
+    /**
+     * IEEE802.11 standard constants.
+     *
+     * See also:
+     *     - https://ieeexplore.ieee.org/document/7786995
+     */
+    public static final int VENDOR_SPECIFIC_IE_ID = 0xdd;
+
+    // TODO: Move to Inet4AddressUtils
+    // See aosp/1455936: NetworkStackConstants can't depend on it as it causes jarjar-related issues
+    // for users of both the net-utils-device-common and net-utils-framework-common libraries.
+    // Jarjar rule management needs to be simplified for that: b/170445871
+
+    /**
+     * Make an Inet4Address from 4 bytes in network byte order.
+     */
+    private static Inet4Address makeInet4Address(byte b1, byte b2, byte b3, byte b4) {
+        try {
+            return (Inet4Address) InetAddress.getByAddress(new byte[] { b1, b2, b3, b4 });
+        } catch (UnknownHostException e) {
+            throw new IllegalArgumentException("addr must be 4 bytes: this should never happen");
+        }
+    }
+
+    private NetworkStackConstants() {
+        throw new UnsupportedOperationException("This class is not to be instantiated");
+    }
+}
diff --git a/staticlibs/framework/com/android/net/module/util/IpUtils.java b/staticlibs/framework/com/android/net/module/util/IpUtils.java
index 54b4cdf..dbc2285 100644
--- a/staticlibs/framework/com/android/net/module/util/IpUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/IpUtils.java
@@ -16,16 +16,15 @@
 
 package com.android.net.module.util;
 
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ShortBuffer;
-
+import static android.system.OsConstants.IPPROTO_ICMPV6;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
 
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+
 /**
  * @hide
  */
@@ -129,16 +128,30 @@
         return (short) sum;
     }
 
+    /**
+     * Calculate the UDP checksum for an UDP packet.
+     */
     public static short udpChecksum(ByteBuffer buf, int ipOffset, int transportOffset) {
         int transportLen = intAbs(buf.getShort(transportOffset + 4));
         return transportChecksum(buf, IPPROTO_UDP, ipOffset, transportOffset, transportLen);
     }
 
+    /**
+     * Calculate the TCP checksum for a TCP packet.
+     */
     public static short tcpChecksum(ByteBuffer buf, int ipOffset, int transportOffset,
             int transportLen) {
         return transportChecksum(buf, IPPROTO_TCP, ipOffset, transportOffset, transportLen);
     }
 
+    /**
+     * Calculate the ICMPv6 checksum for an ICMPv6 packet.
+     */
+    public static short icmpv6Checksum(ByteBuffer buf, int ipOffset, int transportOffset,
+            int transportLen) {
+        return transportChecksum(buf, IPPROTO_ICMPV6, ipOffset, transportOffset, transportLen);
+    }
+
     public static String addressAndPortToString(InetAddress address, int port) {
         return String.format(
                 (address instanceof Inet6Address) ? "[%s]:%d" : "%s:%d",