blob: 95bb5daf2144fda1fd0950c8133fadbb58808792 [file] [log] [blame] [edit]
// Copyright 2012 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "debugd/src/icmp_tool.h"
#include <linux/capability.h>
#include <stdlib.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include "debugd/src/helper_utils.h"
#include "debugd/src/process_with_output.h"
using std::map;
using std::string;
namespace debugd {
namespace {
inline constexpr char kSeccompPolicy[] = "/usr/share/policy/icmp.policy";
inline constexpr uint64_t kCapabilities = CAP_TO_MASK(CAP_NET_RAW);
} // namespace
string ICMPTool::TestICMP(const string& host) {
map<string, string> options;
return TestICMPWithOptions(host, options);
}
string ICMPTool::TestICMPWithOptions(const string& host,
const map<string, string>& options) {
string path;
if (!GetHelperPath("icmp", &path))
return "<path too long>";
ProcessWithOutput p;
p.SetSeccompFilterPolicyFile(kSeccompPolicy);
p.SetCapabilities(kCapabilities);
p.set_separate_stderr(true);
// "--ambient" is required to allow the subprocess ("/usr/bin/ping" in this
// case) to inherit capabilities.
if (!p.Init(/*minijail_extra_args=*/{"--ambient"}))
return "<can't create process>";
p.AddArg(path);
for (const auto& option : options) {
// No need to quote here because chromeos:ProcessImpl (base class of
// ProcessWithOutput) passes arguments as is to helpers/icmp, which will
// check arguments before executing in the shell.
p.AddArg(base::StringPrintf("--%s=%s", option.first.c_str(),
option.second.c_str()));
}
p.AddArg(host);
p.Run();
string out, err;
p.GetOutput(&out);
p.GetError(&err);
if (!err.empty()) {
LOG(ERROR) << "icmp failed: " << err << "; host: " << host;
}
if (out.empty()) {
return err;
}
return out;
}
} // namespace debugd