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