blob: 36849a6e0b5ab61f30f378812949ab0f35cb8e26 [file] [log] [blame]
Darin Petkov50308cd2011-06-01 18:25:07 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/dhcp_config.h"
6
7#include <base/logging.h>
Darin Petkovd1b715b2011-06-02 21:21:22 -07008#include <glib.h>
9
10#include "shill/dhcpcd_proxy.h"
11#include "shill/dhcp_provider.h"
Darin Petkov50308cd2011-06-01 18:25:07 -070012
13namespace shill {
14
Darin Petkovd1b715b2011-06-02 21:21:22 -070015const char DHCPConfig::kDHCPCDPath[] = "/sbin/dhcpcd";
16
17DHCPConfig::DHCPConfig(DHCPProvider *provider, const Device &device)
18 : IPConfig(device),
19 provider_(provider),
20 pid_(0) {
21 VLOG(2) << __func__ << ": " << GetDeviceName();
Darin Petkov50308cd2011-06-01 18:25:07 -070022}
23
24DHCPConfig::~DHCPConfig() {
Darin Petkovd1b715b2011-06-02 21:21:22 -070025 VLOG(2) << __func__ << ": " << GetDeviceName();
26}
27
28bool DHCPConfig::Request() {
29 VLOG(2) << __func__ << ": " << GetDeviceName();
30 if (!pid_) {
31 return Start();
32 }
33 if (!proxy_.get()) {
34 LOG(ERROR)
35 << "Unable to acquire destination address before receiving request.";
36 return false;
37 }
38 return Renew();
39}
40
41bool DHCPConfig::Renew() {
42 VLOG(2) << __func__ << ": " << GetDeviceName();
43 if (!pid_ || !proxy_.get()) {
44 return false;
45 }
46 proxy_->DoRebind(GetDeviceName());
47 return true;
48}
49
50void DHCPConfig::InitProxy(DBus::Connection *connection, const char *service) {
51 if (!proxy_.get()) {
52 proxy_.reset(new DHCPCDProxy(connection, service));
53 }
54}
55
56bool DHCPConfig::Start() {
57 VLOG(2) << __func__ << ": " << GetDeviceName();
58
59 char *argv[4], *envp[1];
60 argv[0] = const_cast<char *>(kDHCPCDPath);
61 argv[1] = const_cast<char *>("-B"); // foreground
62 argv[2] = const_cast<char *>(GetDeviceName().c_str());
63 argv[3] = NULL;
64
65 envp[0] = NULL;
66
67 GPid pid = 0;
68 if (!g_spawn_async(NULL,
69 argv,
70 envp,
71 G_SPAWN_DO_NOT_REAP_CHILD,
72 NULL,
73 NULL,
74 &pid,
75 NULL)) {
76 LOG(ERROR) << "Unable to spawn " << kDHCPCDPath;
77 return false;
78 }
79 pid_ = pid;
80 LOG(INFO) << "Spawned " << kDHCPCDPath << " with pid: " << pid_;
81 provider_->BindPID(pid_, DHCPConfigRefPtr(this));
82 // TODO(petkov): Add an exit watch to cleanup w/ g_spawn_close_pid.
83 return true;
Darin Petkov50308cd2011-06-01 18:25:07 -070084}
85
86} // namespace shill