1//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "apmanager/firewall_manager.h"
18
19#include <base/bind.h>
20#include <brillo/errors/error.h>
21
22#include "apmanager/control_interface.h"
23
24using std::string;
25
26namespace apmanager {
27
28namespace {
29const uint16_t kDhcpServerPort = 67;
30}  // namespace
31
32FirewallManager::FirewallManager() {}
33
34FirewallManager::~FirewallManager() {}
35
36void FirewallManager::Init(ControlInterface* control_interface) {
37  CHECK(!firewall_proxy_) << "Already started";
38  firewall_proxy_ =
39      control_interface->CreateFirewallProxy(
40          base::Bind(&FirewallManager::OnFirewallServiceAppeared,
41                     weak_factory_.GetWeakPtr()),
42          base::Bind(&FirewallManager::OnFirewallServiceVanished,
43                     weak_factory_.GetWeakPtr()));
44}
45
46void FirewallManager::RequestDHCPPortAccess(const std::string& interface) {
47  CHECK(firewall_proxy_) << "Proxy not initialized yet";
48  if (dhcp_access_interfaces_.find(interface) !=
49      dhcp_access_interfaces_.end()) {
50    LOG(ERROR) << "DHCP access already requested for interface: " << interface;
51    return;
52  }
53  firewall_proxy_->RequestUdpPortAccess(interface, kDhcpServerPort);
54  dhcp_access_interfaces_.insert(interface);
55}
56
57void FirewallManager::ReleaseDHCPPortAccess(const std::string& interface) {
58  CHECK(firewall_proxy_) << "Proxy not initialized yet";
59  if (dhcp_access_interfaces_.find(interface) ==
60      dhcp_access_interfaces_.end()) {
61    LOG(ERROR) << "DHCP access has not been requested for interface: "
62               << interface;
63    return;
64  }
65  firewall_proxy_->ReleaseUdpPortAccess(interface, kDhcpServerPort);
66  dhcp_access_interfaces_.erase(interface);
67}
68
69void FirewallManager::OnFirewallServiceAppeared() {
70  LOG(INFO) << __func__;
71  RequestAllPortsAccess();
72}
73
74void FirewallManager::OnFirewallServiceVanished() {
75  // Nothing need to be done.
76  LOG(INFO) << __func__;
77}
78
79void FirewallManager::RequestAllPortsAccess() {
80  // Request access to DHCP port for all specified interfaces.
81  for (const auto& dhcp_interface : dhcp_access_interfaces_) {
82    firewall_proxy_->RequestUdpPortAccess(dhcp_interface, kDhcpServerPort);
83  }
84}
85
86}  // namespace apmanager
87