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

Commit 057bf20e authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN
Browse files

Move DhcpServer to NetworkStack app

Test: atest FrameworksNetTests && atest NetworkStackTests
Bug: b/112869080

Change-Id: I96c40e63e9ceb37b67705bdd4d120307e114715b
parent 952842e5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ java_library {
    srcs: [
        "src/**/*.java",
    ],
    static_libs: [
        "dhcp-packet-lib",
        "frameworks-net-shared-utils",
    ]
}

// Updatable network stack packaged as an application
+153 −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;
    }

    /**
     * Get the clientId associated with this lease, if any.
     *
     * <p>If the lease is not associated to a clientId, this returns null.
     */
    @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));
    }

    /**
     * Determine whether this lease matches a client with the specified parameters.
     * @param clientId clientId of the client if any, or null otherwise.
     * @param hwAddr Hardware address of the client.
     */
    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);
    }

    static String inet4AddrToString(@Nullable Inet4Address addr) {
        return (addr == null) ? "null" : addr.getHostAddress();
    }

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

File added.

Preview size limit exceeded, changes collapsed.

+88 −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.util.FdEventsReader;
import android.os.Handler;
import android.system.Os;

import java.io.FileDescriptor;
import java.net.Inet4Address;
import java.net.InetSocketAddress;

/**
 * A {@link FdEventsReader} to receive and parse {@link DhcpPacket}.
 * @hide
 */
abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payload> {
    static final class Payload {
        protected final byte[] mBytes = new byte[DhcpPacket.MAX_LENGTH];
        protected Inet4Address mSrcAddr;
        protected int mSrcPort;
    }

    DhcpPacketListener(@NonNull Handler handler) {
        super(handler, new Payload());
    }

    @Override
    protected int recvBufSize(@NonNull Payload buffer) {
        return buffer.mBytes.length;
    }

    @Override
    protected final void handlePacket(@NonNull Payload recvbuf, int length) {
        if (recvbuf.mSrcAddr == null) {
            return;
        }

        try {
            final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.mBytes, length,
                    DhcpPacket.ENCAP_BOOTP);
            onReceive(packet, recvbuf.mSrcAddr, recvbuf.mSrcPort);
        } catch (DhcpPacket.ParseException e) {
            logParseError(recvbuf.mBytes, length, e);
        }
    }

    @Override
    protected int readPacket(@NonNull FileDescriptor fd, @NonNull Payload packetBuffer)
            throws Exception {
        final InetSocketAddress addr = new InetSocketAddress();
        final int read = Os.recvfrom(
                fd, packetBuffer.mBytes, 0, packetBuffer.mBytes.length, 0 /* flags */, addr);

        // Buffers with null srcAddr will be dropped in handlePacket()
        packetBuffer.mSrcAddr = inet4AddrOrNull(addr);
        packetBuffer.mSrcPort = addr.getPort();
        return read;
    }

    @Nullable
    private static Inet4Address inet4AddrOrNull(@NonNull InetSocketAddress addr) {
        return addr.getAddress() instanceof Inet4Address
                ? (Inet4Address) addr.getAddress()
                : null;
    }

    protected abstract void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
            int srcPort);
    protected abstract void logParseError(@NonNull byte[] packet, int length,
            @NonNull DhcpPacket.ParseException e);
}
+651 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading