blob: e3cc04f8e2cd7f5db37f164ecbe0181b3ba5cc27 [file] [log] [blame]
Hugo Benichif818c782021-04-10 00:09:50 +09001// Copyright 2021 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 "patchpanel/system.h"
6
Hugo Benichi153c7112021-02-22 17:46:33 +09007#include <fcntl.h>
8#include <sys/stat.h>
Hugo Benichi96ee6f62021-06-28 14:07:20 +09009#include <sys/wait.h>
Hugo Benichi153c7112021-02-22 17:46:33 +090010#include <unistd.h>
11
12#include <base/files/scoped_file.h>
Qijiang Fan80174b72021-08-13 12:48:38 +090013#include <base/logging.h>
Hugo Benichi153c7112021-02-22 17:46:33 +090014
Hugo Benichif818c782021-04-10 00:09:50 +090015namespace patchpanel {
16
Hugo Benichi153c7112021-02-22 17:46:33 +090017namespace {
18
19// /proc/sys/ paths and fragments used for System::SysNetSet
20// Defines the local port range that is used by TCP and UDP traffic to choose
21// the local port (IPv4 and IPv6).
22constexpr const char kSysNetIPLocalPortRangePath[] =
23 "/proc/sys/net/ipv4/ip_local_port_range";
24// Enables/Disables IPv4 forwarding between interfaces.
25constexpr const char kSysNetIPv4ForwardingPath[] =
26 "/proc/sys/net/ipv4/ip_forward";
27// /proc/sys path for controlling connection tracking helper modules
28constexpr const char kSysNetConntrackHelperPath[] =
29 "/proc/sys/net/netfilter/nf_conntrack_helper";
Jason Jeremy Imana183d7a2021-08-06 01:35:40 +090030// Enables/Disables IPv6.
31constexpr const char kSysNetDisableIPv6Path[] =
32 "/proc/sys/net/ipv6/conf/all/disable_ipv6";
Hugo Benichi153c7112021-02-22 17:46:33 +090033// Prefix for IPv4 interface configuration.
34constexpr const char kSysNetIPv4ConfPrefix[] = "/proc/sys/net/ipv4/conf/";
35// Suffix for allowing localhost as a source or destination when routing IPv4.
36constexpr const char kSysNetIPv4RouteLocalnetSuffix[] = "/route_localnet";
37// Enables/Disables IPv6 forwarding between interfaces.
38constexpr const char kSysNetIPv6ForwardingPath[] =
39 "/proc/sys/net/ipv6/conf/all/forwarding";
40// Prefix for IPv6 interface configuration.
41constexpr const char kSysNetIPv6ConfPrefix[] = "/proc/sys/net/ipv6/conf/";
42// Suffix for accepting Router Advertisements on an interface and
43// autoconfiguring it with IPv6 parameters.
44constexpr const char kSysNetIPv6AcceptRaSuffix[] = "/accept_ra";
45
46} // namespace
47
Hugo Benichif818c782021-04-10 00:09:50 +090048int System::Ioctl(int fd, ioctl_req_t request, const char* argp) {
49 return ioctl(fd, request, argp);
50}
51
52int System::Ioctl(int fd, ioctl_req_t request, uint64_t arg) {
53 return Ioctl(fd, request, reinterpret_cast<const char*>(arg));
54}
55
56int System::Ioctl(int fd, ioctl_req_t request, struct ifreq* ifr) {
57 return Ioctl(fd, request, reinterpret_cast<const char*>(ifr));
58}
59
60int System::Ioctl(int fd, ioctl_req_t request, struct rtentry* route) {
61 return Ioctl(fd, request, reinterpret_cast<const char*>(route));
62}
63
Hugo Benichi96ee6f62021-06-28 14:07:20 +090064pid_t System::WaitPid(pid_t pid, int* wstatus, int options) {
65 return waitpid(pid, wstatus, options);
66}
67
Hugo Benichi153c7112021-02-22 17:46:33 +090068bool System::SysNetSet(SysNet target,
69 const std::string& content,
70 const std::string& iface) {
71 std::string path;
72 switch (target) {
73 case SysNet::IPv4Forward:
74 return Write(kSysNetIPv4ForwardingPath, content);
75 case SysNet::IPLocalPortRange:
76 return Write(kSysNetIPLocalPortRangePath, content);
77 case SysNet::IPv4RouteLocalnet:
78 if (iface.empty()) {
79 LOG(ERROR) << "IPv4LocalPortRange requires a valid interface";
80 return false;
81 }
82 return Write(
83 kSysNetIPv4ConfPrefix + iface + kSysNetIPv4RouteLocalnetSuffix,
84 content);
85 case SysNet::IPv6Forward:
86 return Write(kSysNetIPv6ForwardingPath, content);
87 case SysNet::IPv6AcceptRA:
88 if (iface.empty()) {
89 LOG(ERROR) << "IPv6AcceptRA requires a valid interface";
90 return false;
91 }
92 return Write(kSysNetIPv6ConfPrefix + iface + kSysNetIPv6AcceptRaSuffix,
93 content);
94 case ConntrackHelper:
95 return Write(kSysNetConntrackHelperPath, content);
Jason Jeremy Imana183d7a2021-08-06 01:35:40 +090096 case SysNet::IPv6Disable:
97 return Write(kSysNetDisableIPv6Path, content);
Hugo Benichi153c7112021-02-22 17:46:33 +090098 default:
99 LOG(ERROR) << "Unknown SysNet value " << target;
100 return false;
101 }
102}
103
104bool System::Write(const std::string& path, const std::string& content) {
105 base::ScopedFD fd(open(path.c_str(), O_WRONLY | O_TRUNC | O_CLOEXEC));
106 if (!fd.is_valid()) {
107 PLOG(ERROR) << "Failed to open " << path;
108 return false;
109 }
110
111 if (write(fd.get(), content.c_str(), content.size()) != content.size()) {
112 PLOG(ERROR) << "Failed to write \"" << content << "\" to " << path;
113 return false;
114 }
115
116 return true;
117}
118
Hugo Benichif818c782021-04-10 00:09:50 +0900119} // namespace patchpanel