Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8f0416f authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN Committed by android-build-merger
Browse files

Merge changes I2cea553a,Id8d3dcf6,I19e68e88,I35598935,Idd7dc369, ... am: e01b4ce6

am: e06ae295

Change-Id: If4f9e1b498855af05011cbd0f529e346bebd4cbd
parents 52c85422 e06ae295
Loading
Loading
Loading
Loading
+37 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.util.Log;
import android.util.Pair;

import java.io.FileDescriptor;
import java.io.IOException;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
@@ -130,6 +131,17 @@ public class NetworkUtils {
     */
    public native static boolean queryUserAccess(int uid, int netId);

    /**
     * Add an entry into the ARP cache.
     */
    public static void addArpEntry(Inet4Address ipv4Addr, MacAddress ethAddr, String ifname,
            FileDescriptor fd) throws IOException {
        addArpEntry(ethAddr.toByteArray(), ipv4Addr.getAddress(), ifname, fd);
    }

    private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
            FileDescriptor fd) throws IOException;

    /**
     * @see #intToInet4AddressHTL(int)
     * @deprecated Use either {@link #intToInet4AddressHTH(int)}
@@ -149,7 +161,7 @@ public class NetworkUtils {
     * @param hostAddress an int coding for an IPv4 address, where higher-order int byte is
     *                    lower-order IPv4 address byte
     */
    public static InetAddress intToInet4AddressHTL(int hostAddress) {
    public static Inet4Address intToInet4AddressHTL(int hostAddress) {
        return intToInet4AddressHTH(Integer.reverseBytes(hostAddress));
    }

@@ -157,14 +169,14 @@ public class NetworkUtils {
     * Convert a IPv4 address from an integer to an InetAddress (0x01020304 -> 1.2.3.4)
     * @param hostAddress an int coding for an IPv4 address
     */
    public static InetAddress intToInet4AddressHTH(int hostAddress) {
    public static Inet4Address intToInet4AddressHTH(int hostAddress) {
        byte[] addressBytes = { (byte) (0xff & (hostAddress >> 24)),
                (byte) (0xff & (hostAddress >> 16)),
                (byte) (0xff & (hostAddress >> 8)),
                (byte) (0xff & hostAddress) };

        try {
            return InetAddress.getByAddress(addressBytes);
            return (Inet4Address) InetAddress.getByAddress(addressBytes);
        } catch (UnknownHostException e) {
            throw new AssertionError();
        }
@@ -396,6 +408,28 @@ public class NetworkUtils {
        return new Pair<InetAddress, Integer>(address, prefixLength);
    }

    /**
     * Get a prefix mask as Inet4Address for a given prefix length.
     *
     * <p>For example 20 -> 255.255.240.0
     */
    public static Inet4Address getPrefixMaskAsInet4Address(int prefixLength)
            throws IllegalArgumentException {
        return intToInet4AddressHTH(prefixLengthToV4NetmaskIntHTH(prefixLength));
    }

    /**
     * Get the broadcast address for a given prefix.
     *
     * <p>For example 192.168.0.1/24 -> 192.168.0.255
     */
    public static Inet4Address getBroadcastAddress(Inet4Address addr, int prefixLength)
            throws IllegalArgumentException {
        final int intBroadcastAddr = inet4AddressToIntHTH(addr)
                | ~prefixLengthToV4NetmaskIntHTH(prefixLength);
        return intToInet4AddressHTH(intBroadcastAddr);
    }

    /**
     * Check if IP address type is consistent between two InetAddress.
     * @return true if both are the same type.  False otherwise.
+50 −0
Original line number Diff line number Diff line
@@ -323,6 +323,55 @@ static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jin
    return (jboolean) !queryUserAccess(uid, netId);
}

static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst)
{
    if (env->GetArrayLength(addr) != len) {
        return false;
    }
    env->GetByteArrayRegion(addr, 0, len, reinterpret_cast<jbyte*>(dst));
    return true;
}

static void android_net_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
        jbyteArray ipv4Addr, jstring ifname, jobject javaFd)
{
    struct arpreq req = {};
    struct sockaddr_in& netAddrStruct = *reinterpret_cast<sockaddr_in*>(&req.arp_pa);
    struct sockaddr& ethAddrStruct = req.arp_ha;

    ethAddrStruct.sa_family = ARPHRD_ETHER;
    if (!checkLenAndCopy(env, ethAddr, ETH_ALEN, ethAddrStruct.sa_data)) {
        jniThrowException(env, "java/io/IOException", "Invalid ethAddr length");
        return;
    }

    netAddrStruct.sin_family = AF_INET;
    if (!checkLenAndCopy(env, ipv4Addr, sizeof(in_addr), &netAddrStruct.sin_addr)) {
        jniThrowException(env, "java/io/IOException", "Invalid ipv4Addr length");
        return;
    }

    int ifLen = env->GetStringLength(ifname);
    // IFNAMSIZ includes the terminating NULL character
    if (ifLen >= IFNAMSIZ) {
        jniThrowException(env, "java/io/IOException", "ifname too long");
        return;
    }
    env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);

    req.arp_flags = ATF_COM;  // Completed entry (ha valid)
    int fd = jniGetFDFromFileDescriptor(env, javaFd);
    if (fd < 0) {
        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
        return;
    }
    // See also: man 7 arp
    if (ioctl(fd, SIOCSARP, &req)) {
        jniThrowExceptionFmt(env, "java/io/IOException", "ioctl error: %s", strerror(errno));
        return;
    }
}


// ----------------------------------------------------------------------------

@@ -337,6 +386,7 @@ static const JNINativeMethod gNetworkUtilMethods[] = {
    { "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
    { "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
    { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
    { "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) android_net_utils_addArpEntry },
    { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
    { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachRaFilter },
    { "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachControlPacketFilter },
+11 −4
Original line number Diff line number Diff line
@@ -23,11 +23,18 @@ import java.nio.ByteBuffer;
 * This class implements the DHCP-DISCOVER packet.
 */
class DhcpDiscoverPacket extends DhcpPacket {
    /**
     * The IP address of the client which sent this packet.
     */
    final Inet4Address mSrcIp;

    /**
     * Generates a DISCOVER packet with the specified parameters.
     */
    DhcpDiscoverPacket(int transId, short secs, byte[] clientMac, boolean broadcast) {
        super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, INADDR_ANY, clientMac, broadcast);
    DhcpDiscoverPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
            boolean broadcast, Inet4Address srcIp) {
        super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
        mSrcIp = srcIp;
    }

    public String toString() {
@@ -41,8 +48,8 @@ class DhcpDiscoverPacket extends DhcpPacket {
     */
    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
        fillInPacket(encap, INADDR_BROADCAST, INADDR_ANY, destUdp,
                srcUdp, result, DHCP_BOOTREQUEST, mBroadcast);
        fillInPacket(encap, INADDR_BROADCAST, mSrcIp, destUdp, srcUdp, result, DHCP_BOOTREQUEST,
                mBroadcast);
        result.flip();
        return result;
    }
+138 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.net.dhcp;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.MacAddress;
import android.os.SystemClock;
import android.text.TextUtils;

import com.android.internal.util.HexDump;

import java.net.Inet4Address;
import java.util.Arrays;
import java.util.Objects;

/**
 * An IPv4 address assignment done through DHCPv4.
 * @hide
 */
public class DhcpLease {
    public static final long EXPIRATION_NEVER = Long.MAX_VALUE;
    public static final String HOSTNAME_NONE = null;

    @Nullable
    private final byte[] mClientId;
    @NonNull
    private final MacAddress mHwAddr;
    @NonNull
    private final Inet4Address mNetAddr;
    /**
     * Expiration time for the lease, to compare with {@link SystemClock#elapsedRealtime()}.
     */
    private final long mExpTime;
    @Nullable
    private final String mHostname;

    public DhcpLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
            @NonNull Inet4Address netAddr, long expTime, @Nullable String hostname) {
        mClientId = (clientId == null ? null : Arrays.copyOf(clientId, clientId.length));
        mHwAddr = hwAddr;
        mNetAddr = netAddr;
        mExpTime = expTime;
        mHostname = hostname;
    }

    @Nullable
    public byte[] getClientId() {
        if (mClientId == null) {
            return null;
        }
        return Arrays.copyOf(mClientId, mClientId.length);
    }

    @NonNull
    public MacAddress getHwAddr() {
        return mHwAddr;
    }

    @Nullable
    public String getHostname() {
        return mHostname;
    }

    @NonNull
    public Inet4Address getNetAddr() {
        return mNetAddr;
    }

    public long getExpTime() {
        return mExpTime;
    }

    /**
     * Push back the expiration time of this lease. If the provided time is sooner than the original
     * expiration time, the lease time will not be updated.
     *
     * <p>The lease hostname is updated with the provided one if set.
     * @return A {@link DhcpLease} with expiration time set to max(expTime, currentExpTime)
     */
    public DhcpLease renewedLease(long expTime, @Nullable String hostname) {
        return new DhcpLease(mClientId, mHwAddr, mNetAddr, Math.max(expTime, mExpTime),
                (hostname == null ? mHostname : hostname));
    }

    public boolean matchesClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
        if (mClientId != null) {
            return Arrays.equals(mClientId, clientId);
        } else {
            return clientId == null && mHwAddr.equals(hwAddr);
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof DhcpLease)) {
            return false;
        }
        final DhcpLease other = (DhcpLease)obj;
        return Arrays.equals(mClientId, other.mClientId)
                && mHwAddr.equals(other.mHwAddr)
                && mNetAddr.equals(other.mNetAddr)
                && mExpTime == other.mExpTime
                && TextUtils.equals(mHostname, other.mHostname);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mClientId, mHwAddr, mNetAddr, mHostname, mExpTime);
    }

    static String clientIdToString(byte[] bytes) {
        if (bytes == null) {
            return "null";
        }
        return HexDump.toHexString(bytes);
    }

    @Override
    public String toString() {
        return String.format("clientId: %s, hwAddr: %s, netAddr: %s, expTime: %d, hostname: %s",
                clientIdToString(mClientId), mHwAddr.toString(), mNetAddr, mExpTime, mHostname);
    }
}
+538 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading