blob: 429e15e16ce47e6dca57d544d64efdf60c0112a9 [file] [log] [blame]
Thieu Le94eed562012-02-21 15:57:29 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov50308cd2011-06-01 18:25:07 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_DHCP_CONFIG_
6#define SHILL_DHCP_CONFIG_
7
Darin Petkov92c43902011-06-09 20:46:06 -07008#include <base/file_path.h>
Darin Petkovd1b715b2011-06-02 21:21:22 -07009#include <base/memory/scoped_ptr.h>
Darin Petkovaceede32011-07-18 15:32:38 -070010#include <dbus-c++/types.h>
Darin Petkov92c43902011-06-09 20:46:06 -070011#include <glib.h>
Darin Petkove7cb7f82011-06-03 13:21:51 -070012#include <gtest/gtest_prod.h> // for FRIEND_TEST
Darin Petkovd1b715b2011-06-02 21:21:22 -070013
Darin Petkov50308cd2011-06-01 18:25:07 -070014#include "shill/ipconfig.h"
15
16namespace shill {
17
Chris Masone19e30402011-07-19 15:48:47 -070018class ControlInterface;
Darin Petkovd1b715b2011-06-02 21:21:22 -070019class DHCPProvider;
20class DHCPProxyInterface;
Darin Petkova7b89492011-07-27 12:48:17 -070021class EventDispatcher;
Darin Petkov3258a812011-06-23 11:28:45 -070022class GLib;
Darin Petkovab565bb2011-10-06 02:55:51 -070023class ProxyFactory;
Darin Petkovd1b715b2011-06-02 21:21:22 -070024
Paul Stewartd408fdf2012-05-07 17:15:57 -070025// This class provides a DHCP client instance for the device |device_name|.
26// If |request_hostname| is non-empty, it asks the DHCP server to register
27// this hostname on our behalf, for purposes of administration or creating
28// a dynamic DNS entry.
29//
30// The DHPCConfig instance asks the DHCP client to create a lease file
31// containing the name |lease_file_suffix|. If this suffix is the same as
32// |device_name|, the lease is considered to be ephemeral, and the lease
33// file is removed whenever this DHCPConfig instance is no longer needed.
34// Otherwise, the lease file persists and will be re-used in future attempts.
Eric Shienbrood9a245532012-03-07 14:20:39 -050035class DHCPConfig : public IPConfig {
Darin Petkov50308cd2011-06-01 18:25:07 -070036 public:
Darin Petkove7cb7f82011-06-03 13:21:51 -070037 typedef std::map<std::string, DBus::Variant> Configuration;
38
Darin Petkov14c29ec2012-03-02 11:34:19 +010039 static const int kMinMTU;
40
Chris Masone19e30402011-07-19 15:48:47 -070041 DHCPConfig(ControlInterface *control_interface,
Darin Petkova7b89492011-07-27 12:48:17 -070042 EventDispatcher *dispatcher,
Chris Masone19e30402011-07-19 15:48:47 -070043 DHCPProvider *provider,
Darin Petkovf65e9282011-06-21 14:29:56 -070044 const std::string &device_name,
Paul Stewartd32f4842012-01-11 16:08:13 -080045 const std::string &request_hostname,
Paul Stewartd408fdf2012-05-07 17:15:57 -070046 const std::string &lease_file_suffix,
47 bool arp_gateway,
Darin Petkov3258a812011-06-23 11:28:45 -070048 GLib *glib);
Darin Petkov50308cd2011-06-01 18:25:07 -070049 virtual ~DHCPConfig();
50
Darin Petkovd1b715b2011-06-02 21:21:22 -070051 // Inherited from IPConfig.
Darin Petkov92c43902011-06-09 20:46:06 -070052 virtual bool RequestIP();
53 virtual bool RenewIP();
54 virtual bool ReleaseIP();
Darin Petkovd1b715b2011-06-02 21:21:22 -070055
56 // If |proxy_| is not initialized already, sets it to a new D-Bus proxy to
57 // |service|.
Darin Petkova7b89492011-07-27 12:48:17 -070058 void InitProxy(const std::string &service);
Darin Petkovd1b715b2011-06-02 21:21:22 -070059
Darin Petkove7cb7f82011-06-03 13:21:51 -070060 // Processes an Event signal from dhcpcd.
61 void ProcessEventSignal(const std::string &reason,
62 const Configuration &configuration);
63
Darin Petkov50308cd2011-06-01 18:25:07 -070064 private:
Darin Petkov98dd6a02011-06-10 15:12:57 -070065 friend class DHCPConfigTest;
Darin Petkove7cb7f82011-06-03 13:21:51 -070066 FRIEND_TEST(DHCPConfigTest, GetIPv4AddressString);
Darin Petkova7b89492011-07-27 12:48:17 -070067 FRIEND_TEST(DHCPConfigTest, InitProxy);
Darin Petkove7cb7f82011-06-03 13:21:51 -070068 FRIEND_TEST(DHCPConfigTest, ParseConfiguration);
Darin Petkovf9b0ca82011-06-20 12:10:23 -070069 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalFail);
70 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalSuccess);
71 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalUnknown);
Darin Petkov98dd6a02011-06-10 15:12:57 -070072 FRIEND_TEST(DHCPConfigTest, ReleaseIP);
73 FRIEND_TEST(DHCPConfigTest, RenewIP);
74 FRIEND_TEST(DHCPConfigTest, RequestIP);
75 FRIEND_TEST(DHCPConfigTest, Restart);
76 FRIEND_TEST(DHCPConfigTest, RestartNoClient);
Darin Petkov92c43902011-06-09 20:46:06 -070077 FRIEND_TEST(DHCPConfigTest, StartFail);
Paul Stewartd32f4842012-01-11 16:08:13 -080078 FRIEND_TEST(DHCPConfigTest, StartWithHostname);
Paul Stewartd408fdf2012-05-07 17:15:57 -070079 FRIEND_TEST(DHCPConfigTest, StartWithoutArpGateway);
Paul Stewartd32f4842012-01-11 16:08:13 -080080 FRIEND_TEST(DHCPConfigTest, StartWithoutHostname);
Paul Stewartd408fdf2012-05-07 17:15:57 -070081 FRIEND_TEST(DHCPConfigTest, StartWithoutLeaseSuffix);
Darin Petkov98dd6a02011-06-10 15:12:57 -070082 FRIEND_TEST(DHCPConfigTest, Stop);
83 FRIEND_TEST(DHCPProviderTest, CreateConfig);
Darin Petkove7cb7f82011-06-03 13:21:51 -070084
Darin Petkovf9b0ca82011-06-20 12:10:23 -070085 static const char kConfigurationKeyBroadcastAddress[];
86 static const char kConfigurationKeyDNS[];
87 static const char kConfigurationKeyDomainName[];
88 static const char kConfigurationKeyDomainSearch[];
89 static const char kConfigurationKeyIPAddress[];
90 static const char kConfigurationKeyMTU[];
91 static const char kConfigurationKeyRouters[];
92 static const char kConfigurationKeySubnetCIDR[];
93
Thieu Le94eed562012-02-21 15:57:29 -080094 static const int kDHCPCDExitPollMilliseconds;
95 static const int kDHCPCDExitWaitMilliseconds;
Darin Petkovd1b715b2011-06-02 21:21:22 -070096 static const char kDHCPCDPath[];
Darin Petkov92c43902011-06-09 20:46:06 -070097 static const char kDHCPCDPathFormatLease[];
98 static const char kDHCPCDPathFormatPID[];
Darin Petkovd1b715b2011-06-02 21:21:22 -070099
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700100 static const char kReasonBound[];
101 static const char kReasonFail[];
102 static const char kReasonRebind[];
103 static const char kReasonReboot[];
104 static const char kReasonRenew[];
105
Chris Masone0756f232011-07-21 17:24:00 -0700106 static const char kType[];
107
Darin Petkovd1b715b2011-06-02 21:21:22 -0700108 // Starts dhcpcd, returns true on success and false otherwise.
109 bool Start();
110
Darin Petkov92c43902011-06-09 20:46:06 -0700111 // Stops dhcpcd if running.
112 void Stop();
113
Darin Petkov98dd6a02011-06-10 15:12:57 -0700114 // Stops dhcpcd if already running and then starts it. Returns true on success
115 // and false otherwise.
116 bool Restart();
117
Darin Petkove7cb7f82011-06-03 13:21:51 -0700118 // Parses |configuration| into |properties|. Returns true on success, and
119 // false otherwise.
120 bool ParseConfiguration(const Configuration& configuration,
121 IPConfig::Properties *properties);
122
123 // Returns the string representation of the IP address |address|, or an
124 // empty string on failure.
125 std::string GetIPv4AddressString(unsigned int address);
126
Darin Petkov92c43902011-06-09 20:46:06 -0700127 // Called when the dhcpcd client process exits.
128 static void ChildWatchCallback(GPid pid, gint status, gpointer data);
129
Darin Petkov98dd6a02011-06-10 15:12:57 -0700130 // Cleans up remaining state from a running client, if any, including freeing
131 // its GPid, exit watch callback, and state files.
Darin Petkov92c43902011-06-09 20:46:06 -0700132 void CleanupClientState();
133
Darin Petkovab565bb2011-10-06 02:55:51 -0700134 // Store cached copies of singletons for speed/ease of testing.
135 ProxyFactory *proxy_factory_;
136
Darin Petkovd1b715b2011-06-02 21:21:22 -0700137 DHCPProvider *provider_;
138
Paul Stewartd32f4842012-01-11 16:08:13 -0800139 // Hostname to be used in the request. This will be passed to the DHCP
140 // server in the request.
141 std::string request_hostname_;
142
Paul Stewartd408fdf2012-05-07 17:15:57 -0700143 // DHCP lease file suffix, used to differentiate the lease of one interface
144 // or network from another.
145 std::string lease_file_suffix_;
146
147 // Specifies whether to supply an argument to the DHCP client to validate
148 // the acquired IP address using an ARP request to the gateway IP address.
149 bool arp_gateway_;
150
Darin Petkovd1b715b2011-06-02 21:21:22 -0700151 // The PID of the spawned DHCP client. May be 0 if no client has been spawned
152 // yet or the client has died.
Darin Petkov92c43902011-06-09 20:46:06 -0700153 int pid_;
154
155 // Child exit watch callback source tag.
156 unsigned int child_watch_tag_;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700157
158 // The proxy for communicating with the DHCP client.
159 scoped_ptr<DHCPProxyInterface> proxy_;
160
Darin Petkov92c43902011-06-09 20:46:06 -0700161 // Root file path, used for testing.
162 FilePath root_;
163
Darin Petkova7b89492011-07-27 12:48:17 -0700164 EventDispatcher *dispatcher_;
Darin Petkov3258a812011-06-23 11:28:45 -0700165 GLib *glib_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700166
Darin Petkov50308cd2011-06-01 18:25:07 -0700167 DISALLOW_COPY_AND_ASSIGN(DHCPConfig);
168};
169
170} // namespace shill
171
172#endif // SHILL_DHCP_CONFIG_