• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 #ifndef _TETHER_CONTROLLER_H
18 #define _TETHER_CONTROLLER_H
19 
20 #include <list>
21 #include <set>
22 #include <string>
23 
24 #include <netdutils/StatusOr.h>
25 #include <sysutils/SocketClient.h>
26 
27 #include "NetdConstants.h"
28 
29 
30 namespace android {
31 namespace net {
32 
33 class TetherController {
34   private:
35     struct ForwardingDownstream {
36         std::string iface;
37         bool active;
38     };
39 
40     std::list<std::string> mInterfaces;
41 
42     // Map upstream iface -> downstream iface. A pair is in the map if forwarding was enabled at
43     // some point since the controller was initialized.
44     std::multimap<std::string, ForwardingDownstream> mFwdIfaces;
45 
46     // NetId to use for forwarded DNS queries. This may not be the default
47     // network, e.g., in the case where we are tethering to a DUN APN.
48     unsigned               mDnsNetId = 0;
49     std::list<std::string> mDnsForwarders;
50     pid_t                  mDaemonPid = 0;
51     int                    mDaemonFd = -1;
52     std::set<std::string>  mForwardingRequests;
53 
54     struct DnsmasqState {
55         static int sendCmd(int daemonFd, const std::string& cmd);
56 
57         // List of downstream interfaces on which to serve. The format used is:
58         //     update_ifaces|<ifname1>|<ifname2>|...
59         std::string update_ifaces_cmd;
60         // Forwarding (upstream) DNS configuration to use. The format used is:
61         //     update_dns|<hex_socket_mark>|<ip1>|<ip2>|...
62         std::string update_dns_cmd;
63 
64         void clear();
65         int sendAllState(int daemonFd) const;
66     } mDnsmasqState{};
67 
68   public:
69     TetherController();
70     ~TetherController() = default;
71 
72     bool enableForwarding(const char* requester);
73     bool disableForwarding(const char* requester);
74     const std::set<std::string>& getIpfwdRequesterList() const;
75 
76     int startTethering(int num_addrs, char **dhcp_ranges);
77     int startTethering(const std::vector<std::string>& dhcpRanges);
78     int stopTethering();
79     bool isTetheringStarted();
80 
81     unsigned getDnsNetId();
82     int setDnsForwarders(unsigned netId, char **servers, int numServers);
83     int setDnsForwarders(unsigned netId, const std::vector<std::string>& servers);
84     const std::list<std::string> &getDnsForwarders() const;
85 
86     int tetherInterface(const char *interface);
87     int untetherInterface(const char *interface);
88     const std::list<std::string> &getTetheredInterfaceList() const;
89     bool applyDnsInterfaces();
90 
91     int enableNat(const char* intIface, const char* extIface);
92     int disableNat(const char* intIface, const char* extIface);
93     int setupIptablesHooks();
94 
95     class TetherStats {
96       public:
97         TetherStats() = default;
TetherStats(std::string intIfn,std::string extIfn,int64_t rxB,int64_t rxP,int64_t txB,int64_t txP)98         TetherStats(std::string intIfn, std::string extIfn,
99                 int64_t rxB, int64_t rxP,
100                 int64_t txB, int64_t txP)
101                         : intIface(intIfn), extIface(extIfn),
102                             rxBytes(rxB), rxPackets(rxP),
103                             txBytes(txB), txPackets(txP) {};
104         std::string intIface;
105         std::string extIface;
106         int64_t rxBytes = -1;
107         int64_t rxPackets = -1;
108         int64_t txBytes = -1;
109         int64_t txPackets = -1;
110 
addStatsIfMatch(const TetherStats & other)111         bool addStatsIfMatch(const TetherStats& other) {
112             if (intIface == other.intIface && extIface == other.extIface) {
113                 rxBytes   += other.rxBytes;
114                 rxPackets += other.rxPackets;
115                 txBytes   += other.txBytes;
116                 txPackets += other.txPackets;
117                 return true;
118             }
119             return false;
120         }
121     };
122 
123     typedef std::vector<TetherStats> TetherStatsList;
124 
125     netdutils::StatusOr<TetherStatsList> getTetherStats();
126 
127     /*
128      * extraProcessingInfo: contains raw parsed data, and error info.
129      * This strongly requires that setup of the rules is in a specific order:
130      *  in:intIface out:extIface
131      *  in:extIface out:intIface
132      * and the rules are grouped in pairs when more that one tethering was setup.
133      */
134     static int addForwardChainStats(TetherStatsList& statsList, const std::string& iptOutput,
135                                     std::string &extraProcessingInfo);
136 
137     static constexpr const char* LOCAL_FORWARD               = "tetherctrl_FORWARD";
138     static constexpr const char* LOCAL_MANGLE_FORWARD        = "tetherctrl_mangle_FORWARD";
139     static constexpr const char* LOCAL_NAT_POSTROUTING       = "tetherctrl_nat_POSTROUTING";
140     static constexpr const char* LOCAL_RAW_PREROUTING        = "tetherctrl_raw_PREROUTING";
141     static constexpr const char* LOCAL_TETHER_COUNTERS_CHAIN = "tetherctrl_counters";
142 
143     std::mutex lock;
144 
145   private:
146     bool setIpFwdEnabled();
147     std::vector<char*> toCstrVec(const std::vector<std::string>& addrs);
148     int setupIPv6CountersChain();
149     static std::string makeTetherCountingRule(const char *if1, const char *if2);
150     ForwardingDownstream* findForwardingDownstream(const std::string& intIface,
151         const std::string& extIface);
152     void addForwardingPair(const std::string& intIface, const std::string& extIface);
153     void markForwardingPairDisabled(const std::string& intIface, const std::string& extIface);
154 
155     bool isForwardingPairEnabled(const std::string& intIface, const std::string& extIface);
156     bool isAnyForwardingEnabledOnUpstream(const std::string& extIface);
157     bool isAnyForwardingPairEnabled();
158     bool tetherCountingRuleExists(const std::string& iface1, const std::string& iface2);
159 
160     int setDefaults();
161     int setTetherGlobalAlertRule();
162     int setForwardRules(bool set, const char *intIface, const char *extIface);
163     int setTetherCountingRules(bool add, const char *intIface, const char *extIface);
164 
165     static void addStats(TetherStatsList& statsList, const TetherStats& stats);
166 
167     // For testing.
168     friend class TetherControllerTest;
169     static int (*iptablesRestoreFunction)(IptablesTarget, const std::string&, std::string *);
170 };
171 
172 }  // namespace net
173 }  // namespace android
174 
175 #endif
176