1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net.dhcp;
18
19import android.util.Log;
20
21import java.net.InetAddress;
22import java.net.Inet4Address;
23import java.nio.ByteBuffer;
24
25/**
26 * This class implements the DHCP-REQUEST packet.
27 */
28class DhcpRequestPacket extends DhcpPacket {
29    /**
30     * Generates a REQUEST packet with the specified parameters.
31     */
32    DhcpRequestPacket(int transId, InetAddress clientIp, byte[] clientMac,
33                      boolean broadcast) {
34        super(transId, clientIp, Inet4Address.ANY, Inet4Address.ANY,
35          Inet4Address.ANY, clientMac, broadcast);
36    }
37
38    public String toString() {
39        String s = super.toString();
40        return s + " REQUEST, desired IP " + mRequestedIp + " from host '"
41            + mHostName + "', param list length "
42            + (mRequestedParams == null ? 0 : mRequestedParams.length);
43    }
44
45    /**
46     * Fills in a packet with the requested REQUEST attributes.
47     */
48    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
49        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
50
51        fillInPacket(encap, Inet4Address.ALL, Inet4Address.ANY, destUdp, srcUdp,
52            result, DHCP_BOOTREQUEST, mBroadcast);
53        result.flip();
54        return result;
55    }
56
57    /**
58     * Adds the optional parameters to the client-generated REQUEST packet.
59     */
60    void finishPacket(ByteBuffer buffer) {
61        byte[] clientId = new byte[7];
62
63        // assemble client identifier
64        clientId[0] = CLIENT_ID_ETHER;
65        System.arraycopy(mClientMac, 0, clientId, 1, 6);
66
67        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_REQUEST);
68        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
69        addTlv(buffer, DHCP_REQUESTED_IP, mRequestedIp);
70        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
71        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, clientId);
72        addTlvEnd(buffer);
73    }
74
75    /**
76     * Notifies the specified state machine of the REQUEST packet parameters.
77     */
78    public void doNextOp(DhcpStateMachine machine) {
79        InetAddress clientRequest =
80            mRequestedIp == null ? mClientIp : mRequestedIp;
81        Log.v(TAG, "requested IP is " + mRequestedIp + " and client IP is " +
82            mClientIp);
83        machine.onRequestReceived(mBroadcast, mTransId, mClientMac,
84            clientRequest, mRequestedParams, mHostName);
85    }
86}
87