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

Commit 7da02ad3 authored by Stan Chesnutt's avatar Stan Chesnutt
Browse files

DHCP core classes, defining data, behavior, and state transitions for the DHCP

protocol.  The DHCP client and DHCP server classes are not included in this
commit: still working out some integration issues with ethernet & wifi services

Change-Id: I0c9cc48b7d960005b73ecb757c1fa66f0eb68471
parent ad3ec1b9
Loading
Loading
Loading
Loading
+110 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2010 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 java.net.InetAddress;
import java.net.Inet4Address;
import java.nio.ByteBuffer;
import java.util.List;

/**
 * This class implements the DHCP-ACK packet.
 */
class DhcpAckPacket extends DhcpPacket {

    /**
     * The address of the server which sent this packet.
     */
    private final InetAddress mSrcIp;

    DhcpAckPacket(int transId, boolean broadcast, InetAddress serverAddress,
                  InetAddress clientIp, byte[] clientMac) {
        super(transId, Inet4Address.ANY, clientIp, Inet4Address.ANY,
            Inet4Address.ANY, clientMac, broadcast);
        mBroadcast = broadcast;
        mSrcIp = serverAddress;
    }

    public String toString() {
        String s = super.toString();
        String dnsServers = " DNS servers: ";

        for (InetAddress dnsServer: mDnsServers) {
            dnsServers += dnsServer.toString() + " ";
        }

        return s + " ACK: your new IP " + mYourIp +
                ", netmask " + mSubnetMask +
                ", gateway " + mGateway + dnsServers +
                ", lease time " + mLeaseTime;
    }

    /**
     * Fills in a packet with the requested ACK parameters.
     */
    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
        InetAddress destIp = mBroadcast ? Inet4Address.ALL : mYourIp;
        InetAddress srcIp = mBroadcast ? Inet4Address.ANY : mSrcIp;

        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
            DHCP_BOOTREPLY, mBroadcast);
        result.flip();
        return result;
    }

    /**
     * Adds the optional parameters to the client-generated ACK packet.
     */
    void finishPacket(ByteBuffer buffer) {
        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_ACK);
        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
        addTlv(buffer, DHCP_LEASE_TIME, mLeaseTime);

        // the client should renew at 1/2 the lease-expiry interval
        if (mLeaseTime != null) {
            addTlv(buffer, DHCP_RENEWAL_TIME,
                Integer.valueOf(mLeaseTime.intValue() / 2));
        }

        addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask);
        addTlv(buffer, DHCP_ROUTER, mGateway);
        addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName);
        addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
        addTlv(buffer, DHCP_DNS_SERVER, mDnsServers);
        addTlvEnd(buffer);
    }

    /**
     * Un-boxes an Integer, returning 0 if a null reference is supplied.
     */
    private static final int getInt(Integer v) {
        if (v == null) {
            return 0;
        } else {
            return v.intValue();
        }
    }

    /**
     * Notifies the specified state machine of the ACK packet parameters.
     */
    public void doNextOp(DhcpStateMachine machine) {
        machine.onAckReceived(mYourIp, mSubnetMask, mGateway, mDnsServers,
            mServerIdentifier, getInt(mLeaseTime));
    }
}
+65 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2010 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 java.net.InetAddress;
import java.nio.ByteBuffer;

/**
 * This class implements the DHCP-DECLINE packet.
 */
class DhcpDeclinePacket extends DhcpPacket {
    /**
     * Generates a DECLINE packet with the specified parameters.
     */
    DhcpDeclinePacket(int transId, InetAddress clientIp, InetAddress yourIp,
                      InetAddress nextIp, InetAddress relayIp,
                      byte[] clientMac) {
        super(transId, clientIp, yourIp, nextIp, relayIp, clientMac, false);
    }

    public String toString() {
        String s = super.toString();
        return s + " DECLINE";
    }

    /**
     * Fills in a packet with the requested DECLINE attributes.
     */
    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);

        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
            DHCP_BOOTREQUEST, false);
        result.flip();
        return result;
    }

    /**
     * Adds optional parameters to the DECLINE packet.
     */
    void finishPacket(ByteBuffer buffer) {
        // None needed
    }

    /**
     * Informs the state machine of the arrival of a DECLINE packet.
     */
    public void doNextOp(DhcpStateMachine machine) {
        machine.onDeclineReceived(mClientMac, mRequestedIp);
    }
}
+71 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2010 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 java.net.InetAddress;
import java.net.Inet4Address;
import java.nio.ByteBuffer;

/**
 * This class implements the DHCP-DISCOVER packet.
 */
class DhcpDiscoverPacket extends DhcpPacket {
    /**
     * Generates a DISCOVER packet with the specified parameters.
     */
    DhcpDiscoverPacket(int transId, byte[] clientMac, boolean broadcast) {
        super(transId, Inet4Address.ANY, Inet4Address.ANY, Inet4Address.ANY,
            Inet4Address.ANY, clientMac, broadcast);
    }

    public String toString() {
        String s = super.toString();
        return s + " DISCOVER " +
                (mBroadcast ? "broadcast " : "unicast ");
    }

    /**
     * Fills in a packet with the requested DISCOVER parameters.
     */
    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
        InetAddress destIp = Inet4Address.ALL;

        fillInPacket(encap, Inet4Address.ALL, Inet4Address.ANY, destUdp, srcUdp,
            result, DHCP_BOOTREQUEST, true);
        result.flip();
        return result;
    }

    /**
     * Adds optional parameters to a DISCOVER packet.
     */
    void finishPacket(ByteBuffer buffer) {
        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DISCOVER);
        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
        addTlvEnd(buffer);
    }

    /**
     * Informs the state machine of the arrival of a DISCOVER packet.
     */
    public void doNextOp(DhcpStateMachine machine) {
        // currently omitted: host name
        machine.onDiscoverReceived(mBroadcast, mTransId, mClientMac,
            mRequestedParams);
    }
}
+76 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2010 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 java.net.InetAddress;
import java.nio.ByteBuffer;

/**
 * This class implements the (unused) DHCP-INFORM packet.
 */
class DhcpInformPacket extends DhcpPacket {
    /**
     * Generates an INFORM packet with the specified parameters.
     */
    DhcpInformPacket(int transId, InetAddress clientIp, InetAddress yourIp,
                     InetAddress nextIp, InetAddress relayIp,
                     byte[] clientMac) {
        super(transId, clientIp, yourIp, nextIp, relayIp, clientMac, false);
    }

    public String toString() {
        String s = super.toString();
        return s + " INFORM";
    }

    /**
     * Builds an INFORM packet.
     */
    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);

        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
            DHCP_BOOTREQUEST, false);
        result.flip();
        return result;
    }

    /**
     * Adds additional parameters to the INFORM packet.
     */
    void finishPacket(ByteBuffer buffer) {
        byte[] clientId = new byte[7];

        clientId[0] = CLIENT_ID_ETHER;
        System.arraycopy(mClientMac, 0, clientId, 1, 6);

        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_REQUEST);
        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
        addTlvEnd(buffer);
    }

    /**
     * Informs the state machine of the arrival of an INFORM packet.  Not
     * used currently.
     */
    public void doNextOp(DhcpStateMachine machine) {
        InetAddress clientRequest =
            mRequestedIp == null ? mClientIp : mRequestedIp;
        machine.onInformReceived(mTransId, mClientMac, clientRequest,
            mRequestedParams);
    }
}
+72 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2010 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 java.net.InetAddress;
import java.net.Inet4Address;
import java.nio.ByteBuffer;

/**
 * This class implements the DHCP-NAK packet.
 */
class DhcpNakPacket extends DhcpPacket {
    /**
     * Generates a NAK packet with the specified parameters.
     */
    DhcpNakPacket(int transId, InetAddress clientIp, InetAddress yourIp,
                  InetAddress nextIp, InetAddress relayIp,
                  byte[] clientMac) {
        super(transId, Inet4Address.ANY, Inet4Address.ANY, nextIp, relayIp,
            clientMac, false);
    }

    public String toString() {
        String s = super.toString();
        return s + " NAK, reason " + (mMessage == null ? "(none)" : mMessage);
    }

    /**
     * Fills in a packet with the requested NAK attributes.
     */
    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
        InetAddress destIp = mClientIp;
        InetAddress srcIp = mYourIp;

        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
            DHCP_BOOTREPLY, mBroadcast);
        result.flip();
        return result;
    }

    /**
     * Adds the optional parameters to the client-generated NAK packet.
     */
    void finishPacket(ByteBuffer buffer) {
        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_NAK);
        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
        addTlv(buffer, DHCP_MESSAGE, mMessage);
        addTlvEnd(buffer);
    }

    /**
     * Notifies the specified state machine of the newly-arrived NAK packet.
     */
    public void doNextOp(DhcpStateMachine machine) {
        machine.onNakReceived();
    }
}
Loading