1 /*
2  * Copyright 2018, 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 "bridge.h"
18 #include "bridge_builder.h"
19 #include "commander.h"
20 #include "commands/wifi_command.h"
21 #include "log.h"
22 #include "monitor.h"
23 #include "poller.h"
24 #include "utils.h"
25 #include "wifi_forwarder.h"
26 
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
29 
30 #include <cutils/properties.h>
31 
32 #include <functional>
33 
34 static const char kBridgeName[] = "br0";
35 static const char kNetworkBridgedProperty[] = "vendor.network.bridged";
36 
usage(const char * name)37 static void usage(const char* name) {
38     LOGE("Usage: %s --if-prefix <prefix> --bridge <if1,if2,...>", name);
39     LOGE("  <prefix> indicates the name of network interfaces to configure.");
40     LOGE("  <ip/mask> is the base IP address to assign to the first interface");
41     LOGE("  and mask indicates the netmask and broadcast to set.");
42     LOGE("  Additionally mask is used to determine the address");
43     LOGE("  for the second interface by skipping ahead one subnet");
44     LOGE("  and the size of the subnet is indicated by <mask>");
45 }
46 
addBridgeInterfaces(Bridge & bridge,const char * interfaces)47 static Result addBridgeInterfaces(Bridge& bridge, const char* interfaces) {
48     std::vector<std::string> ifNames = explode(interfaces, ',');
49 
50     for (const auto& ifName : ifNames) {
51         Result res = bridge.addInterface(ifName);
52         if (!res) {
53             return res;
54         }
55     }
56     return Result::success();
57 }
58 
main(int argc,char * argv[])59 int main(int argc, char* argv[]) {
60     const char* interfacePrefix = nullptr;
61     const char* bridgeInterfaces = nullptr;
62 
63     for (int i = 1; i < argc; ++i) {
64         if (strcmp(argv[i], "--if-prefix") == 0 && i + 1 < argc) {
65             interfacePrefix = argv[++i];
66         } else if (strcmp(argv[i], "--bridge") == 0 && i + 1 < argc) {
67             bridgeInterfaces = argv[++i];
68         } else {
69             LOGE("Unknown parameter '%s'", argv[i]);
70             usage(argv[0]);
71             return 1;
72         }
73     }
74 
75     if (interfacePrefix == nullptr) {
76         LOGE("Missing parameter --if-prefix");
77     }
78     if (bridgeInterfaces == nullptr) {
79         LOGE("Missing parameter --bridge");
80     }
81     if (interfacePrefix == nullptr || bridgeInterfaces == nullptr) {
82         usage(argv[0]);
83         return 1;
84     }
85 
86     Bridge bridge(kBridgeName);
87     Result res = bridge.init();
88     if (!res) {
89         LOGE("%s", res.c_str());
90         return 1;
91     }
92     res = addBridgeInterfaces(bridge, bridgeInterfaces);
93     if (!res) {
94         LOGE("%s", res.c_str());
95         return 1;
96     }
97 
98     BridgeBuilder bridgeBuilder(bridge, interfacePrefix);
99 
100     property_set(kNetworkBridgedProperty, "1");
101 
102     Monitor monitor;
103 
104     monitor.setOnInterfaceState(std::bind(&BridgeBuilder::onInterfaceState,
105                                           &bridgeBuilder,
106                                           std::placeholders::_1,
107                                           std::placeholders::_2,
108                                           std::placeholders::_3));
109 
110     res = monitor.init();
111     if (!res) {
112         LOGE("%s", res.c_str());
113         return 1;
114     }
115 
116     Commander commander;
117     res = commander.init();
118     if (!res) {
119         LOGE("%s", res.c_str());
120         return 1;
121     }
122 
123     WifiCommand wifiCommand(bridge);
124     commander.registerCommand("wifi", &wifiCommand);
125 
126     Poller poller;
127     poller.addPollable(&monitor);
128     poller.addPollable(&commander);
129 
130     return poller.run();
131 }
132 
133