blob: 6fd594947c12fab7c4de0a8be28e703e4bf82885 [file] [log] [blame]
// Copyright (C) 2015 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
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
#include <random>
#include <string>
#include <base/cancelable_callback.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/strings/stringprintf.h>
#include <shill/net/byte_string.h>
#include <shill/net/io_handler_factory_container.h>
#include <shill/net/sockets.h>
#include "dhcp_client/dhcp.h"
#include "dhcp_client/dhcp_message.h"
#include "dhcp_client/event_dispatcher_interface.h"
#include "shill/net/arp_client.h"
namespace dhcp_client {
class ServiceAdaptorInterface;
class SocketUtil;
class DHCPV4 : public DHCP {
DHCPV4(ServiceAdaptorInterface* adaptor,
const std::string& interface_name,
const shill::ByteString& hardware_address,
unsigned int interface_index,
const std::string& network_id,
bool request_hostname,
bool arp_gateway,
bool unicast_arp,
EventDispatcherInterface* event_dispatcher);
virtual ~DHCPV4();
bool Start();
void Stop();
void ArpProbeReplyReceivedTask(int fd);
void ArpProbeReplyTimeoutTask();
void CheckIpCollision();
bool HasALease();
bool MakePacket(const DHCPMessage& message, shill::ByteString* buffer);
bool MakeRawPacket(const DHCPMessage& message, shill::ByteString* buffer);
void OnReadError(const std::string& error_msg);
void ParseRawPacket(shill::InputData* data);
bool ReadLease();
bool WriteLease();
bool SendDiscover();
bool SendRequest();
bool SendRelease();
// Validate the IP and UDP header and return the total headers length.
// Return -1 if any header is invalid.
int ValidatePacketHeader(const unsigned char* buffer, size_t len);
bool ValidateOptions(const DHCPMessage& msg);
void ResetState();
// Util functions.
uint32_t MasktoCIDR(uint32_t subnet_mask);
const std::string IPtoString(uint32_t ip);
void HandleOffer(const DHCPMessage& msg);
void HandleAck(const DHCPMessage& msg);
void HandleNak(const DHCPMessage& msg);
// Handle the case that it is time for a renewal process.
void RenewalTask();
// Handle the case that the client didn't reiceive a timely
// renewal responese from server. Therefore it is time for
// a rebinding process.
void RebindTask();
// Emit events through RPC adaptor
void EmitEvent(const std::string& reason);
// Serivce RPC adaptor
ServiceAdaptorInterface* adaptor_;
// Interface parameters.
std::string interface_name_;
shill::ByteString hardware_address_;
unsigned int interface_index_;
// Unique network/connection identifier,
// lease will persist to storage if this identifier is specified.
std::string network_id_;
// DHCP IPv4 configurations:
// Request hostname from server.
bool request_hostname_;
// ARP for default gateway.
bool arp_gateway_;
// Enable unicast ARP on renew.
bool unicast_arp_;
std::unique_ptr<shill::ArpClient> arp_client_;
EventDispatcherInterface* event_dispatcher_;
shill::IOHandlerFactory *io_handler_factory_;
std::unique_ptr<shill::IOHandler> input_handler_;
std::unique_ptr<shill::IOHandler> receive_arp_response_handler_;
base::WeakPtrFactory<DHCPV4> weak_ptr_factory_;
// DHCP state variables.
State state_;
uint32_t server_identifier_;
uint32_t transaction_id_;
uint32_t offered_ip_address_;
uint32_t subnet_mask_;
// Client IP address.
// It can be either a bounded ip address or an INADDR_ANY constant.
uint32_t client_ip_;
// Server IP address.
// It can be either a bounded server address or an INADDR_BROADCAST constant.
uint32_t server_ip_;
// Interface mtu.
uint16_t interface_mtu_;
// Broadcast address.
uint32_t broadcast_address_;
// Aka Default Gateway.
std::vector<uint32_t> router_;
// Domain Name Servers.
std::vector<uint32_t> dns_server_;
// Vendor specific information.
shill::ByteString vendor_specific_info_;
// Domain name.
std::string domain_name_;
// Timeout callbacks.
base::CancelableClosure renewal_task_callback_;
base::CancelableClosure rebind_task_callback_;
base::CancelableClosure arp_probe_reply_timeout_task_callback_;
// Socket used for sending and receiving DHCP messages.
int raw_socket_;
// Socket used for sending unicast DHCP messages.
int udp_socket_;
// Helper class with wrapped socket relavent functions.
std::unique_ptr<shill::Sockets> sockets_;
// Helper class handling sockets for DHCP.
SocketUtil* socket_util_;
std::default_random_engine random_engine_;
} // namespace dhcp_client