blob: 209df0449e0244703487f9f3c6773bc9048b169d [file] [log] [blame]
San Mehat873f2142010-01-14 10:25:07 -08001/*
2 * Copyright (C) 2007 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
17package com.android.server;
18
Jeff Sharkey4529bb62011-12-14 10:31:54 -080019import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070020import static android.Manifest.permission.DUMP;
Jeff Sharkeyaf75c332011-11-18 12:41:12 -080021import static android.Manifest.permission.SHUTDOWN;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070022import static android.net.NetworkStats.SET_DEFAULT;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070023import static android.net.NetworkStats.TAG_NONE;
24import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyae2c1812011-10-04 13:11:40 -070025import static android.net.TrafficStats.UID_TETHERING;
Lorenzo Colitti79751842013-02-28 16:16:03 +090026import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080027import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
28import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080029import static com.android.server.NetworkManagementService.NetdResponseCode.IpFwdStatusResult;
30import static com.android.server.NetworkManagementService.NetdResponseCode.TetherDnsFwdTgtListResult;
31import static com.android.server.NetworkManagementService.NetdResponseCode.TetherInterfaceListResult;
32import static com.android.server.NetworkManagementService.NetdResponseCode.TetherStatusResult;
33import static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsResult;
34import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
Jeff Sharkeya63ba592011-07-19 23:47:12 -070035import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070036
San Mehat873f2142010-01-14 10:25:07 -080037import android.content.Context;
San Mehat4d02d002010-01-22 16:07:46 -080038import android.net.INetworkManagementEventObserver;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070039import android.net.InterfaceConfiguration;
Robert Greenwalted126402011-01-28 15:34:55 -080040import android.net.LinkAddress;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070041import android.net.NetworkStats;
Robert Greenwalted126402011-01-28 15:34:55 -080042import android.net.NetworkUtils;
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070043import android.net.RouteInfo;
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -080044import android.net.wifi.WifiConfiguration;
45import android.net.wifi.WifiConfiguration.KeyMgmt;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070046import android.os.Binder;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070047import android.os.Handler;
San Mehat873f2142010-01-14 10:25:07 -080048import android.os.INetworkManagementService;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070049import android.os.Process;
Jeff Sharkey3df273e2011-12-15 15:47:12 -080050import android.os.RemoteCallbackList;
51import android.os.RemoteException;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070052import android.os.ServiceManager;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070053import android.os.SystemClock;
Marco Nelissen62dbb222010-02-18 10:56:30 -080054import android.os.SystemProperties;
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -080055import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080056import android.util.Slog;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -070057import android.util.SparseBooleanArray;
San Mehat873f2142010-01-14 10:25:07 -080058
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070059import com.android.internal.app.IBatteryStats;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070060import com.android.internal.net.NetworkStatsFactory;
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070061import com.android.internal.util.Preconditions;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080062import com.android.server.NativeDaemonConnector.Command;
Jeff Sharkey56cd6462013-06-07 15:09:15 -070063import com.android.server.NativeDaemonConnector.SensitiveArg;
Jeff Sharkey69ddab42012-08-25 00:05:46 -070064import com.android.server.net.LockdownVpnTracker;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070065import com.google.android.collect.Maps;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070066
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070067import java.io.BufferedReader;
68import java.io.DataInputStream;
San Mehat873f2142010-01-14 10:25:07 -080069import java.io.File;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070070import java.io.FileDescriptor;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070071import java.io.FileInputStream;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070072import java.io.IOException;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070073import java.io.InputStreamReader;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070074import java.io.PrintWriter;
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070075import java.net.Inet4Address;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070076import java.net.InetAddress;
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -070077import java.net.InterfaceAddress;
78import java.net.NetworkInterface;
79import java.net.SocketException;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070080import java.util.ArrayList;
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -070081import java.util.Collection;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070082import java.util.HashMap;
83import java.util.Map;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070084import java.util.NoSuchElementException;
85import java.util.StringTokenizer;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -070086import java.util.concurrent.CountDownLatch;
San Mehat873f2142010-01-14 10:25:07 -080087
88/**
89 * @hide
90 */
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070091public class NetworkManagementService extends INetworkManagementService.Stub
92 implements Watchdog.Monitor {
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070093 private static final String TAG = "NetworkManagementService";
Dianne Hackborncef65ee2010-09-30 18:27:22 -070094 private static final boolean DBG = false;
Kenny Root305bcbf2010-09-03 07:56:38 -070095 private static final String NETD_TAG = "NetdConnector";
96
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080097 private static final String ADD = "add";
98 private static final String REMOVE = "remove";
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070099
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700100 private static final String ALLOW = "allow";
101 private static final String DENY = "deny";
102
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700103 private static final String DEFAULT = "default";
104 private static final String SECONDARY = "secondary";
105
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700106 /**
107 * Name representing {@link #setGlobalAlert(long)} limit when delivered to
108 * {@link INetworkManagementEventObserver#limitReached(String, String)}.
109 */
110 public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
111
San Mehat873f2142010-01-14 10:25:07 -0800112 class NetdResponseCode {
JP Abgrall12b933d2011-07-14 18:09:22 -0700113 /* Keep in sync with system/netd/ResponseCode.h */
San Mehat873f2142010-01-14 10:25:07 -0800114 public static final int InterfaceListResult = 110;
115 public static final int TetherInterfaceListResult = 111;
116 public static final int TetherDnsFwdTgtListResult = 112;
San Mehat72759df2010-01-19 13:50:37 -0800117 public static final int TtyListResult = 113;
San Mehat873f2142010-01-14 10:25:07 -0800118
119 public static final int TetherStatusResult = 210;
120 public static final int IpFwdStatusResult = 211;
San Mehated4fc8a2010-01-22 12:28:36 -0800121 public static final int InterfaceGetCfgResult = 213;
Robert Greenwalte3253922010-02-18 09:23:25 -0800122 public static final int SoftapStatusResult = 214;
San Mehat91cac642010-03-31 14:31:36 -0700123 public static final int InterfaceRxCounterResult = 216;
124 public static final int InterfaceTxCounterResult = 217;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700125 public static final int QuotaCounterResult = 220;
126 public static final int TetheringStatsResult = 221;
Selim Gurun84c00c62012-02-27 15:42:38 -0800127 public static final int DnsProxyQueryResult = 222;
Lorenzo Colitti79751842013-02-28 16:16:03 +0900128 public static final int ClatdStatusResult = 223;
Robert Greenwalte3253922010-02-18 09:23:25 -0800129
130 public static final int InterfaceChange = 600;
JP Abgrall12b933d2011-07-14 18:09:22 -0700131 public static final int BandwidthControl = 601;
Haoyu Bai6b7358d2012-07-17 16:36:50 -0700132 public static final int InterfaceClassActivity = 613;
San Mehat873f2142010-01-14 10:25:07 -0800133 }
134
135 /**
136 * Binder context for this service
137 */
138 private Context mContext;
139
140 /**
141 * connector object for communicating with netd
142 */
143 private NativeDaemonConnector mConnector;
144
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700145 private final Handler mMainHandler = new Handler();
146
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700147 private Thread mThread;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700148 private CountDownLatch mConnectedSignal = new CountDownLatch(1);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700149
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800150 private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
151 new RemoteCallbackList<INetworkManagementEventObserver>();
San Mehat4d02d002010-01-22 16:07:46 -0800152
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700153 private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
154
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700155 private Object mQuotaLock = new Object();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700156 /** Set of interfaces with active quotas. */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700157 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700158 /** Set of interfaces with active alerts. */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700159 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700160 /** Set of UIDs with active reject rules. */
161 private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
162
Haoyu Bai04124232012-06-28 15:26:19 -0700163 private Object mIdleTimerLock = new Object();
164 /** Set of interfaces with active idle timers. */
165 private static class IdleTimerParams {
166 public final int timeout;
167 public final String label;
168 public int networkCount;
169
170 IdleTimerParams(int timeout, String label) {
171 this.timeout = timeout;
172 this.label = label;
173 this.networkCount = 1;
174 }
175 }
176 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
177
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700178 private volatile boolean mBandwidthControlEnabled;
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700179 private volatile boolean mFirewallEnabled;
Jeff Sharkey350083e2011-06-29 10:45:16 -0700180
San Mehat873f2142010-01-14 10:25:07 -0800181 /**
182 * Constructs a new NetworkManagementService instance
183 *
184 * @param context Binder context for this service
185 */
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700186 private NetworkManagementService(Context context) {
San Mehat873f2142010-01-14 10:25:07 -0800187 mContext = context;
San Mehat4d02d002010-01-22 16:07:46 -0800188
Marco Nelissen62dbb222010-02-18 10:56:30 -0800189 if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
190 return;
191 }
192
San Mehat873f2142010-01-14 10:25:07 -0800193 mConnector = new NativeDaemonConnector(
Robert Greenwalt5a0c3202012-05-22 16:07:46 -0700194 new NetdCallbackReceiver(), "netd", 10, NETD_TAG, 160);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700195 mThread = new Thread(mConnector, NETD_TAG);
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700196
197 // Add ourself to the Watchdog monitors.
198 Watchdog.getInstance().addMonitor(this);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700199 }
200
201 public static NetworkManagementService create(Context context) throws InterruptedException {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700202 final NetworkManagementService service = new NetworkManagementService(context);
203 final CountDownLatch connectedSignal = service.mConnectedSignal;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700204 if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
205 service.mThread.start();
206 if (DBG) Slog.d(TAG, "Awaiting socket connection");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700207 connectedSignal.await();
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700208 if (DBG) Slog.d(TAG, "Connected");
209 return service;
San Mehat873f2142010-01-14 10:25:07 -0800210 }
211
Jeff Sharkey350083e2011-06-29 10:45:16 -0700212 public void systemReady() {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700213 prepareNativeDaemon();
214 if (DBG) Slog.d(TAG, "Prepared");
Jeff Sharkey350083e2011-06-29 10:45:16 -0700215 }
216
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800217 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800218 public void registerObserver(INetworkManagementEventObserver observer) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800219 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800220 mObservers.register(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800221 }
222
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800223 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800224 public void unregisterObserver(INetworkManagementEventObserver observer) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800225 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800226 mObservers.unregister(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800227 }
228
229 /**
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700230 * Notify our observers of an interface status change
San Mehat4d02d002010-01-22 16:07:46 -0800231 */
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700232 private void notifyInterfaceStatusChanged(String iface, boolean up) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800233 final int length = mObservers.beginBroadcast();
234 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800235 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800236 mObservers.getBroadcastItem(i).interfaceStatusChanged(iface, up);
237 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900238 } catch (RuntimeException e) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700239 }
240 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800241 mObservers.finishBroadcast();
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700242 }
243
244 /**
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700245 * Notify our observers of an interface link state change
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700246 * (typically, an Ethernet cable has been plugged-in or unplugged).
247 */
248 private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800249 final int length = mObservers.beginBroadcast();
250 for (int i = 0; i < length; i++) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700251 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800252 mObservers.getBroadcastItem(i).interfaceLinkStateChanged(iface, up);
253 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900254 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800255 }
256 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800257 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800258 }
259
260 /**
261 * Notify our observers of an interface addition.
262 */
263 private void notifyInterfaceAdded(String iface) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800264 final int length = mObservers.beginBroadcast();
265 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800266 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800267 mObservers.getBroadcastItem(i).interfaceAdded(iface);
268 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900269 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800270 }
271 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800272 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800273 }
274
275 /**
276 * Notify our observers of an interface removal.
277 */
278 private void notifyInterfaceRemoved(String iface) {
Jeff Sharkey89b8a212011-10-11 11:58:11 -0700279 // netd already clears out quota and alerts for removed ifaces; update
280 // our sanity-checking state.
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700281 mActiveAlerts.remove(iface);
282 mActiveQuotas.remove(iface);
Jeff Sharkey89b8a212011-10-11 11:58:11 -0700283
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800284 final int length = mObservers.beginBroadcast();
285 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800286 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800287 mObservers.getBroadcastItem(i).interfaceRemoved(iface);
288 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900289 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800290 }
291 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800292 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800293 }
294
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700295 /**
JP Abgrall12b933d2011-07-14 18:09:22 -0700296 * Notify our observers of a limit reached.
297 */
298 private void notifyLimitReached(String limitName, String iface) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800299 final int length = mObservers.beginBroadcast();
300 for (int i = 0; i < length; i++) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700301 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800302 mObservers.getBroadcastItem(i).limitReached(limitName, iface);
303 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900304 } catch (RuntimeException e) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700305 }
306 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800307 mObservers.finishBroadcast();
JP Abgrall12b933d2011-07-14 18:09:22 -0700308 }
309
310 /**
Haoyu Baidb3c8672012-06-20 14:29:57 -0700311 * Notify our observers of a change in the data activity state of the interface
312 */
313 private void notifyInterfaceClassActivity(String label, boolean active) {
314 final int length = mObservers.beginBroadcast();
315 for (int i = 0; i < length; i++) {
316 try {
317 mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(label, active);
318 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900319 } catch (RuntimeException e) {
Haoyu Baidb3c8672012-06-20 14:29:57 -0700320 }
321 }
322 mObservers.finishBroadcast();
323 }
324
325 /**
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700326 * Prepare native daemon once connected, enabling modules and pushing any
327 * existing in-memory rules.
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700328 */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700329 private void prepareNativeDaemon() {
330 mBandwidthControlEnabled = false;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700331
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700332 // only enable bandwidth control when support exists
333 final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists();
334 if (hasKernelSupport) {
335 Slog.d(TAG, "enabling bandwidth control");
336 try {
337 mConnector.execute("bandwidth", "enable");
338 mBandwidthControlEnabled = true;
339 } catch (NativeDaemonConnectorException e) {
340 Log.wtf(TAG, "problem enabling bandwidth controls", e);
341 }
342 } else {
343 Slog.d(TAG, "not enabling bandwidth control");
344 }
345
346 SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0");
347
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700348 if (mBandwidthControlEnabled) {
349 try {
350 IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"))
351 .noteNetworkStatsEnabled();
352 } catch (RemoteException e) {
353 }
354 }
355
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700356 // push any existing quota or UID rules
357 synchronized (mQuotaLock) {
358 int size = mActiveQuotas.size();
359 if (size > 0) {
360 Slog.d(TAG, "pushing " + size + " active quota rules");
361 final HashMap<String, Long> activeQuotas = mActiveQuotas;
362 mActiveQuotas = Maps.newHashMap();
363 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
364 setInterfaceQuota(entry.getKey(), entry.getValue());
365 }
366 }
367
368 size = mActiveAlerts.size();
369 if (size > 0) {
370 Slog.d(TAG, "pushing " + size + " active alert rules");
371 final HashMap<String, Long> activeAlerts = mActiveAlerts;
372 mActiveAlerts = Maps.newHashMap();
373 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
374 setInterfaceAlert(entry.getKey(), entry.getValue());
375 }
376 }
377
378 size = mUidRejectOnQuota.size();
379 if (size > 0) {
380 Slog.d(TAG, "pushing " + size + " active uid rules");
381 final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota;
382 mUidRejectOnQuota = new SparseBooleanArray();
383 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
384 setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i));
385 }
386 }
387 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700388
389 // TODO: Push any existing firewall state
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700390 setFirewallEnabled(mFirewallEnabled || LockdownVpnTracker.isEnabled());
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700391 }
San Mehat4d02d002010-01-22 16:07:46 -0800392
San Mehat873f2142010-01-14 10:25:07 -0800393 //
394 // Netd Callback handling
395 //
396
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700397 private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks {
398 @Override
San Mehat873f2142010-01-14 10:25:07 -0800399 public void onDaemonConnected() {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700400 // event is dispatched from internal NDC thread, so we prepare the
401 // daemon back on main thread.
402 if (mConnectedSignal != null) {
403 mConnectedSignal.countDown();
404 mConnectedSignal = null;
405 } else {
406 mMainHandler.post(new Runnable() {
407 @Override
408 public void run() {
409 prepareNativeDaemon();
410 }
411 });
412 }
San Mehat873f2142010-01-14 10:25:07 -0800413 }
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700414
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700415 @Override
San Mehat873f2142010-01-14 10:25:07 -0800416 public boolean onEvent(int code, String raw, String[] cooked) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700417 switch (code) {
418 case NetdResponseCode.InterfaceChange:
419 /*
420 * a network interface change occured
421 * Format: "NNN Iface added <name>"
422 * "NNN Iface removed <name>"
423 * "NNN Iface changed <name> <up/down>"
424 * "NNN Iface linkstatus <name> <up/down>"
425 */
426 if (cooked.length < 4 || !cooked[1].equals("Iface")) {
427 throw new IllegalStateException(
428 String.format("Invalid event from daemon (%s)", raw));
429 }
430 if (cooked[2].equals("added")) {
431 notifyInterfaceAdded(cooked[3]);
432 return true;
433 } else if (cooked[2].equals("removed")) {
434 notifyInterfaceRemoved(cooked[3]);
435 return true;
436 } else if (cooked[2].equals("changed") && cooked.length == 5) {
437 notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
438 return true;
439 } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
440 notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
441 return true;
442 }
Robert Greenwalte3253922010-02-18 09:23:25 -0800443 throw new IllegalStateException(
444 String.format("Invalid event from daemon (%s)", raw));
JP Abgrall12b933d2011-07-14 18:09:22 -0700445 // break;
446 case NetdResponseCode.BandwidthControl:
447 /*
448 * Bandwidth control needs some attention
449 * Format: "NNN limit alert <alertName> <ifaceName>"
450 */
451 if (cooked.length < 5 || !cooked[1].equals("limit")) {
452 throw new IllegalStateException(
453 String.format("Invalid event from daemon (%s)", raw));
454 }
455 if (cooked[2].equals("alert")) {
456 notifyLimitReached(cooked[3], cooked[4]);
457 return true;
458 }
459 throw new IllegalStateException(
460 String.format("Invalid event from daemon (%s)", raw));
461 // break;
Haoyu Baidb3c8672012-06-20 14:29:57 -0700462 case NetdResponseCode.InterfaceClassActivity:
463 /*
464 * An network interface class state changed (active/idle)
465 * Format: "NNN IfaceClass <active/idle> <label>"
466 */
467 if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
468 throw new IllegalStateException(
469 String.format("Invalid event from daemon (%s)", raw));
470 }
471 boolean isActive = cooked[2].equals("active");
472 notifyInterfaceClassActivity(cooked[3], isActive);
473 return true;
474 // break;
JP Abgrall12b933d2011-07-14 18:09:22 -0700475 default: break;
Robert Greenwalte3253922010-02-18 09:23:25 -0800476 }
477 return false;
San Mehat873f2142010-01-14 10:25:07 -0800478 }
479 }
480
San Mehated4fc8a2010-01-22 12:28:36 -0800481
San Mehat873f2142010-01-14 10:25:07 -0800482 //
483 // INetworkManagementService members
484 //
485
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800486 @Override
487 public String[] listInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800488 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700489 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800490 return NativeDaemonEvent.filterMessageList(
491 mConnector.executeForList("interface", "list"), InterfaceListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700492 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800493 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700494 }
San Mehated4fc8a2010-01-22 12:28:36 -0800495 }
496
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800497 @Override
498 public InterfaceConfiguration getInterfaceConfig(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800499 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800500
501 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700502 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800503 event = mConnector.execute("interface", "getcfg", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700504 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800505 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700506 }
San Mehated4fc8a2010-01-22 12:28:36 -0800507
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800508 event.checkCode(InterfaceGetCfgResult);
509
510 // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz flag1 flag2 flag3
511 final StringTokenizer st = new StringTokenizer(event.getMessage());
San Mehated4fc8a2010-01-22 12:28:36 -0800512
Kenny Roota80ce062010-06-01 13:23:53 -0700513 InterfaceConfiguration cfg;
San Mehated4fc8a2010-01-22 12:28:36 -0800514 try {
Kenny Roota80ce062010-06-01 13:23:53 -0700515 cfg = new InterfaceConfiguration();
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800516 cfg.setHardwareAddress(st.nextToken(" "));
Robert Greenwalted126402011-01-28 15:34:55 -0800517 InetAddress addr = null;
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800518 int prefixLength = 0;
Kenny Roota80ce062010-06-01 13:23:53 -0700519 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800520 addr = NetworkUtils.numericToInetAddress(st.nextToken());
Robert Greenwalte5903732011-02-22 16:00:42 -0800521 } catch (IllegalArgumentException iae) {
522 Slog.e(TAG, "Failed to parse ipaddr", iae);
Kenny Roota80ce062010-06-01 13:23:53 -0700523 }
524
525 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800526 prefixLength = Integer.parseInt(st.nextToken());
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800527 } catch (NumberFormatException nfe) {
528 Slog.e(TAG, "Failed to parse prefixLength", nfe);
Kenny Roota80ce062010-06-01 13:23:53 -0700529 }
Robert Greenwalt04808c22010-12-13 17:01:41 -0800530
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800531 cfg.setLinkAddress(new LinkAddress(addr, prefixLength));
532 while (st.hasMoreTokens()) {
533 cfg.setFlag(st.nextToken());
534 }
Kenny Roota80ce062010-06-01 13:23:53 -0700535 } catch (NoSuchElementException nsee) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800536 throw new IllegalStateException("Invalid response from daemon: " + event);
San Mehated4fc8a2010-01-22 12:28:36 -0800537 }
San Mehated4fc8a2010-01-22 12:28:36 -0800538 return cfg;
539 }
540
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800541 @Override
542 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800543 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800544 LinkAddress linkAddr = cfg.getLinkAddress();
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800545 if (linkAddr == null || linkAddr.getAddress() == null) {
546 throw new IllegalStateException("Null LinkAddress given");
Robert Greenwalted126402011-01-28 15:34:55 -0800547 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800548
549 final Command cmd = new Command("interface", "setcfg", iface,
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800550 linkAddr.getAddress().getHostAddress(),
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800551 linkAddr.getNetworkPrefixLength());
552 for (String flag : cfg.getFlags()) {
553 cmd.appendArg(flag);
554 }
555
Kenny Roota80ce062010-06-01 13:23:53 -0700556 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800557 mConnector.execute(cmd);
Kenny Roota80ce062010-06-01 13:23:53 -0700558 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800559 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700560 }
San Mehat873f2142010-01-14 10:25:07 -0800561 }
562
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800563 @Override
564 public void setInterfaceDown(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800565 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800566 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800567 ifcg.setInterfaceDown();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800568 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700569 }
570
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800571 @Override
572 public void setInterfaceUp(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800573 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800574 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800575 ifcg.setInterfaceUp();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800576 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700577 }
578
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800579 @Override
580 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800581 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sheriff73293612011-09-14 12:31:56 -0700582 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800583 mConnector.execute(
584 "interface", "ipv6privacyextensions", iface, enable ? "enable" : "disable");
Irfan Sheriff73293612011-09-14 12:31:56 -0700585 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800586 throw e.rethrowAsParcelableException();
Irfan Sheriff73293612011-09-14 12:31:56 -0700587 }
588 }
589
Irfan Sherifff5600612011-06-16 10:26:28 -0700590 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
591 IPv6 addresses on interface down, but we need to do full clean up here */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800592 @Override
593 public void clearInterfaceAddresses(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800594 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sherifff5600612011-06-16 10:26:28 -0700595 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800596 mConnector.execute("interface", "clearaddrs", iface);
Irfan Sherifff5600612011-06-16 10:26:28 -0700597 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800598 throw e.rethrowAsParcelableException();
Irfan Sherifff5600612011-06-16 10:26:28 -0700599 }
600 }
601
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800602 @Override
603 public void enableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800604 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700605 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800606 mConnector.execute("interface", "ipv6", iface, "enable");
repo sync7960d9f2011-09-29 12:40:02 -0700607 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800608 throw e.rethrowAsParcelableException();
repo sync7960d9f2011-09-29 12:40:02 -0700609 }
610 }
611
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800612 @Override
613 public void disableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800614 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700615 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800616 mConnector.execute("interface", "ipv6", iface, "disable");
repo sync7960d9f2011-09-29 12:40:02 -0700617 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800618 throw e.rethrowAsParcelableException();
repo sync7960d9f2011-09-29 12:40:02 -0700619 }
620 }
621
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800622 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700623 public void addRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800624 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700625 modifyRoute(interfaceName, ADD, route, DEFAULT);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700626 }
627
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800628 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700629 public void removeRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800630 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700631 modifyRoute(interfaceName, REMOVE, route, DEFAULT);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700632 }
633
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800634 @Override
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700635 public void addSecondaryRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800636 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700637 modifyRoute(interfaceName, ADD, route, SECONDARY);
638 }
639
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800640 @Override
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700641 public void removeSecondaryRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800642 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700643 modifyRoute(interfaceName, REMOVE, route, SECONDARY);
644 }
645
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800646 private void modifyRoute(String interfaceName, String action, RouteInfo route, String type) {
647 final Command cmd = new Command("interface", "route", action, interfaceName, type);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700648
649 // create triplet: dest-ip-addr prefixlength gateway-ip-addr
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800650 final LinkAddress la = route.getDestination();
651 cmd.appendArg(la.getAddress().getHostAddress());
652 cmd.appendArg(la.getNetworkPrefixLength());
653
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700654 if (route.getGateway() == null) {
655 if (la.getAddress() instanceof Inet4Address) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800656 cmd.appendArg("0.0.0.0");
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700657 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800658 cmd.appendArg("::0");
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700659 }
660 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800661 cmd.appendArg(route.getGateway().getHostAddress());
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700662 }
663
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800664 try {
665 mConnector.execute(cmd);
666 } catch (NativeDaemonConnectorException e) {
667 throw e.rethrowAsParcelableException();
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700668 }
669 }
670
671 private ArrayList<String> readRouteList(String filename) {
672 FileInputStream fstream = null;
673 ArrayList<String> list = new ArrayList<String>();
674
675 try {
676 fstream = new FileInputStream(filename);
677 DataInputStream in = new DataInputStream(fstream);
678 BufferedReader br = new BufferedReader(new InputStreamReader(in));
679 String s;
680
681 // throw away the title line
682
683 while (((s = br.readLine()) != null) && (s.length() != 0)) {
684 list.add(s);
685 }
686 } catch (IOException ex) {
687 // return current list, possibly empty
688 } finally {
689 if (fstream != null) {
690 try {
691 fstream.close();
692 } catch (IOException ex) {}
693 }
694 }
695
696 return list;
697 }
698
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800699 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700700 public RouteInfo[] getRoutes(String interfaceName) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800701 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700702 ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
703
704 // v4 routes listed as:
705 // iface dest-addr gateway-addr flags refcnt use metric netmask mtu window IRTT
706 for (String s : readRouteList("/proc/net/route")) {
707 String[] fields = s.split("\t");
708
709 if (fields.length > 7) {
710 String iface = fields[0];
711
712 if (interfaceName.equals(iface)) {
713 String dest = fields[1];
714 String gate = fields[2];
715 String flags = fields[3]; // future use?
716 String mask = fields[7];
717 try {
718 // address stored as a hex string, ex: 0014A8C0
719 InetAddress destAddr =
720 NetworkUtils.intToInetAddress((int)Long.parseLong(dest, 16));
721 int prefixLength =
722 NetworkUtils.netmaskIntToPrefixLength(
723 (int)Long.parseLong(mask, 16));
724 LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
725
726 // address stored as a hex string, ex 0014A8C0
727 InetAddress gatewayAddr =
728 NetworkUtils.intToInetAddress((int)Long.parseLong(gate, 16));
729
Wink Saville7b5fd052013-03-15 05:07:04 +0000730 RouteInfo route = new RouteInfo(linkAddress, gatewayAddr);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700731 routes.add(route);
732 } catch (Exception e) {
733 Log.e(TAG, "Error parsing route " + s + " : " + e);
734 continue;
735 }
736 }
737 }
738 }
739
740 // v6 routes listed as:
741 // dest-addr prefixlength ?? ?? gateway-addr ?? ?? ?? ?? iface
742 for (String s : readRouteList("/proc/net/ipv6_route")) {
743 String[]fields = s.split("\\s+");
744 if (fields.length > 9) {
745 String iface = fields[9].trim();
746 if (interfaceName.equals(iface)) {
747 String dest = fields[0];
748 String prefix = fields[1];
749 String gate = fields[4];
750
751 try {
752 // prefix length stored as a hex string, ex 40
753 int prefixLength = Integer.parseInt(prefix, 16);
754
755 // address stored as a 32 char hex string
756 // ex fe800000000000000000000000000000
757 InetAddress destAddr = NetworkUtils.hexToInet6Address(dest);
758 LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
759
760 InetAddress gateAddr = NetworkUtils.hexToInet6Address(gate);
761
Wink Saville7b5fd052013-03-15 05:07:04 +0000762 RouteInfo route = new RouteInfo(linkAddress, gateAddr);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700763 routes.add(route);
764 } catch (Exception e) {
765 Log.e(TAG, "Error parsing route " + s + " : " + e);
766 continue;
767 }
768 }
769 }
770 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800771 return routes.toArray(new RouteInfo[routes.size()]);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700772 }
773
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800774 @Override
San Mehat873f2142010-01-14 10:25:07 -0800775 public void shutdown() {
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800776 // TODO: remove from aidl if nobody calls externally
777 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800778
Joe Onorato8a9b2202010-02-26 18:56:32 -0800779 Slog.d(TAG, "Shutting down");
San Mehat873f2142010-01-14 10:25:07 -0800780 }
781
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800782 @Override
San Mehat873f2142010-01-14 10:25:07 -0800783 public boolean getIpForwardingEnabled() throws IllegalStateException{
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800784 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800785
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800786 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700787 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800788 event = mConnector.execute("ipfwd", "status");
Kenny Roota80ce062010-06-01 13:23:53 -0700789 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800790 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700791 }
San Mehat873f2142010-01-14 10:25:07 -0800792
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800793 // 211 Forwarding enabled
794 event.checkCode(IpFwdStatusResult);
795 return event.getMessage().endsWith("enabled");
San Mehat873f2142010-01-14 10:25:07 -0800796 }
797
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800798 @Override
799 public void setIpForwardingEnabled(boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800800 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800801 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800802 mConnector.execute("ipfwd", enable ? "enable" : "disable");
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800803 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800804 throw e.rethrowAsParcelableException();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800805 }
San Mehat873f2142010-01-14 10:25:07 -0800806 }
807
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800808 @Override
809 public void startTethering(String[] dhcpRange) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800810 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700811 // cmd is "tether start first_start first_stop second_start second_stop ..."
812 // an odd number of addrs will fail
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800813
814 final Command cmd = new Command("tether", "start");
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700815 for (String d : dhcpRange) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800816 cmd.appendArg(d);
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700817 }
Kenny Roota80ce062010-06-01 13:23:53 -0700818
819 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800820 mConnector.execute(cmd);
Kenny Roota80ce062010-06-01 13:23:53 -0700821 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800822 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700823 }
San Mehat873f2142010-01-14 10:25:07 -0800824 }
825
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800826 @Override
827 public void stopTethering() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800828 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700829 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800830 mConnector.execute("tether", "stop");
Kenny Roota80ce062010-06-01 13:23:53 -0700831 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800832 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700833 }
San Mehat873f2142010-01-14 10:25:07 -0800834 }
835
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800836 @Override
837 public boolean isTetheringStarted() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800838 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800839
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800840 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700841 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800842 event = mConnector.execute("tether", "status");
Kenny Roota80ce062010-06-01 13:23:53 -0700843 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800844 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700845 }
San Mehat873f2142010-01-14 10:25:07 -0800846
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800847 // 210 Tethering services started
848 event.checkCode(TetherStatusResult);
849 return event.getMessage().endsWith("started");
San Mehat873f2142010-01-14 10:25:07 -0800850 }
Matthew Xiefe19f122012-07-12 16:03:32 -0700851
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800852 @Override
853 public void tetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800854 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700855 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800856 mConnector.execute("tether", "interface", "add", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700857 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800858 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700859 }
San Mehat873f2142010-01-14 10:25:07 -0800860 }
861
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800862 @Override
San Mehat873f2142010-01-14 10:25:07 -0800863 public void untetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800864 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700865 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800866 mConnector.execute("tether", "interface", "remove", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700867 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800868 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700869 }
San Mehat873f2142010-01-14 10:25:07 -0800870 }
871
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800872 @Override
873 public String[] listTetheredInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800874 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700875 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800876 return NativeDaemonEvent.filterMessageList(
877 mConnector.executeForList("tether", "interface", "list"),
878 TetherInterfaceListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700879 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800880 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700881 }
San Mehat873f2142010-01-14 10:25:07 -0800882 }
883
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800884 @Override
885 public void setDnsForwarders(String[] dns) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800886 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800887
888 final Command cmd = new Command("tether", "dns", "set");
889 for (String s : dns) {
890 cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
891 }
892
San Mehat873f2142010-01-14 10:25:07 -0800893 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800894 mConnector.execute(cmd);
895 } catch (NativeDaemonConnectorException e) {
896 throw e.rethrowAsParcelableException();
San Mehat873f2142010-01-14 10:25:07 -0800897 }
898 }
899
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800900 @Override
901 public String[] getDnsForwarders() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800902 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700903 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800904 return NativeDaemonEvent.filterMessageList(
905 mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700906 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800907 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700908 }
San Mehat873f2142010-01-14 10:25:07 -0800909 }
910
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800911 private void modifyNat(String action, String internalInterface, String externalInterface)
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700912 throws SocketException {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800913 final Command cmd = new Command("nat", action, internalInterface, externalInterface);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700914
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800915 final NetworkInterface internalNetworkInterface = NetworkInterface.getByName(
916 internalInterface);
Robert Greenwalte83d1812011-11-21 14:44:39 -0800917 if (internalNetworkInterface == null) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800918 cmd.appendArg("0");
Robert Greenwalte83d1812011-11-21 14:44:39 -0800919 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800920 Collection<InterfaceAddress> interfaceAddresses = internalNetworkInterface
921 .getInterfaceAddresses();
922 cmd.appendArg(interfaceAddresses.size());
Robert Greenwalte83d1812011-11-21 14:44:39 -0800923 for (InterfaceAddress ia : interfaceAddresses) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800924 InetAddress addr = NetworkUtils.getNetworkPart(
925 ia.getAddress(), ia.getNetworkPrefixLength());
926 cmd.appendArg(addr.getHostAddress() + "/" + ia.getNetworkPrefixLength());
Robert Greenwalte83d1812011-11-21 14:44:39 -0800927 }
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700928 }
929
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800930 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800931 mConnector.execute(cmd);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800932 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800933 throw e.rethrowAsParcelableException();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800934 }
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700935 }
936
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800937 @Override
938 public void enableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800939 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700940 try {
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700941 modifyNat("enable", internalInterface, externalInterface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800942 } catch (SocketException e) {
943 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700944 }
San Mehat873f2142010-01-14 10:25:07 -0800945 }
946
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800947 @Override
948 public void disableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800949 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700950 try {
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700951 modifyNat("disable", internalInterface, externalInterface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800952 } catch (SocketException e) {
953 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700954 }
San Mehat873f2142010-01-14 10:25:07 -0800955 }
San Mehat72759df2010-01-19 13:50:37 -0800956
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800957 @Override
958 public String[] listTtys() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800959 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700960 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800961 return NativeDaemonEvent.filterMessageList(
962 mConnector.executeForList("list_ttys"), TtyListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700963 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800964 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700965 }
San Mehat72759df2010-01-19 13:50:37 -0800966 }
967
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800968 @Override
969 public void attachPppd(
970 String tty, String localAddr, String remoteAddr, String dns1Addr, String dns2Addr) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800971 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat72759df2010-01-19 13:50:37 -0800972 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800973 mConnector.execute("pppd", "attach", tty,
Robert Greenwalte5903732011-02-22 16:00:42 -0800974 NetworkUtils.numericToInetAddress(localAddr).getHostAddress(),
975 NetworkUtils.numericToInetAddress(remoteAddr).getHostAddress(),
976 NetworkUtils.numericToInetAddress(dns1Addr).getHostAddress(),
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800977 NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress());
Kenny Roota80ce062010-06-01 13:23:53 -0700978 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800979 throw e.rethrowAsParcelableException();
San Mehat72759df2010-01-19 13:50:37 -0800980 }
981 }
982
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800983 @Override
984 public void detachPppd(String tty) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800985 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700986 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800987 mConnector.execute("pppd", "detach", tty);
Kenny Roota80ce062010-06-01 13:23:53 -0700988 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800989 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700990 }
San Mehat72759df2010-01-19 13:50:37 -0800991 }
Robert Greenwaltce1200d2010-02-18 11:25:54 -0800992
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800993 @Override
994 public void startAccessPoint(
Irfan Sheriff90542752012-06-19 15:44:35 -0700995 WifiConfiguration wifiConfig, String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800996 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700997 try {
Irfan Sheriffcb30b222011-07-29 20:54:52 -0700998 wifiFirmwareReload(wlanIface, "AP");
Kenny Roota80ce062010-06-01 13:23:53 -0700999 if (wifiConfig == null) {
Irfan Sheriff90542752012-06-19 15:44:35 -07001000 mConnector.execute("softap", "set", wlanIface);
Kenny Roota80ce062010-06-01 13:23:53 -07001001 } else {
Irfan Sheriff90542752012-06-19 15:44:35 -07001002 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
Dmitry Shmidtdfddc9e2013-04-16 13:20:35 -07001003 "broadcast", getSecurityType(wifiConfig),
Kenny Root36062542013-06-10 11:09:28 -07001004 new SensitiveArg(wifiConfig.preSharedKey));
Kenny Roota80ce062010-06-01 13:23:53 -07001005 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001006 mConnector.execute("softap", "startap");
Kenny Roota80ce062010-06-01 13:23:53 -07001007 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001008 throw e.rethrowAsParcelableException();
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -08001009 }
Irfan Sheriff5321aef2010-02-12 12:35:59 -08001010 }
1011
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001012 private static String getSecurityType(WifiConfiguration wifiConfig) {
Irfan Sheriffec8d23a2011-02-16 17:00:33 -08001013 switch (wifiConfig.getAuthType()) {
1014 case KeyMgmt.WPA_PSK:
1015 return "wpa-psk";
1016 case KeyMgmt.WPA2_PSK:
1017 return "wpa2-psk";
1018 default:
1019 return "open";
1020 }
1021 }
1022
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001023 /* @param mode can be "AP", "STA" or "P2P" */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001024 @Override
1025 public void wifiFirmwareReload(String wlanIface, String mode) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001026 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001027 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001028 mConnector.execute("softap", "fwreload", wlanIface, mode);
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001029 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001030 throw e.rethrowAsParcelableException();
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001031 }
1032 }
1033
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001034 @Override
1035 public void stopAccessPoint(String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001036 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001037 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001038 mConnector.execute("softap", "stopap");
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001039 wifiFirmwareReload(wlanIface, "STA");
Kenny Roota80ce062010-06-01 13:23:53 -07001040 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001041 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001042 }
Irfan Sheriff5321aef2010-02-12 12:35:59 -08001043 }
1044
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001045 @Override
Irfan Sheriff90542752012-06-19 15:44:35 -07001046 public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001047 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001048 try {
1049 if (wifiConfig == null) {
Irfan Sheriff90542752012-06-19 15:44:35 -07001050 mConnector.execute("softap", "set", wlanIface);
Kenny Roota80ce062010-06-01 13:23:53 -07001051 } else {
Irfan Sheriff90542752012-06-19 15:44:35 -07001052 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
Dmitry Shmidtdfddc9e2013-04-16 13:20:35 -07001053 "broadcast", getSecurityType(wifiConfig),
Kenny Root36062542013-06-10 11:09:28 -07001054 new SensitiveArg(wifiConfig.preSharedKey));
Kenny Roota80ce062010-06-01 13:23:53 -07001055 }
1056 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001057 throw e.rethrowAsParcelableException();
Irfan Sheriffc2f54c22010-03-18 14:02:22 -07001058 }
1059 }
San Mehat91cac642010-03-31 14:31:36 -07001060
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001061 @Override
Haoyu Bai04124232012-06-28 15:26:19 -07001062 public void addIdleTimer(String iface, int timeout, String label) {
1063 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1064
1065 if (DBG) Slog.d(TAG, "Adding idletimer");
1066
1067 synchronized (mIdleTimerLock) {
1068 IdleTimerParams params = mActiveIdleTimers.get(iface);
1069 if (params != null) {
1070 // the interface already has idletimer, update network count
1071 params.networkCount++;
1072 return;
1073 }
1074
1075 try {
1076 mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
1077 } catch (NativeDaemonConnectorException e) {
1078 throw e.rethrowAsParcelableException();
1079 }
1080 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
1081 }
1082 }
1083
1084 @Override
1085 public void removeIdleTimer(String iface) {
1086 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1087
1088 if (DBG) Slog.d(TAG, "Removing idletimer");
1089
1090 synchronized (mIdleTimerLock) {
1091 IdleTimerParams params = mActiveIdleTimers.get(iface);
1092 if (params == null || --(params.networkCount) > 0) {
1093 return;
1094 }
1095
1096 try {
1097 mConnector.execute("idletimer", "remove", iface,
1098 Integer.toString(params.timeout), params.label);
1099 } catch (NativeDaemonConnectorException e) {
1100 throw e.rethrowAsParcelableException();
1101 }
1102 mActiveIdleTimers.remove(iface);
1103 }
1104 }
1105
1106 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001107 public NetworkStats getNetworkStatsSummaryDev() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001108 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001109 try {
1110 return mStatsFactory.readNetworkStatsSummaryDev();
1111 } catch (IOException e) {
1112 throw new IllegalStateException(e);
1113 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001114 }
1115
1116 @Override
1117 public NetworkStats getNetworkStatsSummaryXt() {
1118 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001119 try {
1120 return mStatsFactory.readNetworkStatsSummaryXt();
1121 } catch (IOException e) {
1122 throw new IllegalStateException(e);
1123 }
Jeff Sharkeyae2c1812011-10-04 13:11:40 -07001124 }
1125
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001126 @Override
Jeff Sharkey9a13f362011-04-26 16:25:36 -07001127 public NetworkStats getNetworkStatsDetail() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001128 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001129 try {
1130 return mStatsFactory.readNetworkStatsDetail(UID_ALL);
1131 } catch (IOException e) {
1132 throw new IllegalStateException(e);
1133 }
San Mehat91cac642010-03-31 14:31:36 -07001134 }
1135
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001136 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001137 public void setInterfaceQuota(String iface, long quotaBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001138 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001139
Jeff Sharkey350083e2011-06-29 10:45:16 -07001140 // silently discard when control disabled
1141 // TODO: eventually migrate to be always enabled
1142 if (!mBandwidthControlEnabled) return;
1143
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001144 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001145 if (mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001146 throw new IllegalStateException("iface " + iface + " already has quota");
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001147 }
1148
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001149 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001150 // TODO: support quota shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001151 mConnector.execute("bandwidth", "setiquota", iface, quotaBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001152 mActiveQuotas.put(iface, quotaBytes);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001153 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001154 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001155 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001156 }
1157 }
1158
1159 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001160 public void removeInterfaceQuota(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001161 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001162
Jeff Sharkey350083e2011-06-29 10:45:16 -07001163 // silently discard when control disabled
1164 // TODO: eventually migrate to be always enabled
1165 if (!mBandwidthControlEnabled) return;
1166
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001167 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001168 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001169 // TODO: eventually consider throwing
1170 return;
1171 }
1172
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001173 mActiveQuotas.remove(iface);
1174 mActiveAlerts.remove(iface);
Jeff Sharkey38ddeaa2011-11-08 13:04:22 -08001175
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001176 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001177 // TODO: support quota shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001178 mConnector.execute("bandwidth", "removeiquota", iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001179 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001180 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001181 }
1182 }
1183 }
1184
1185 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001186 public void setInterfaceAlert(String iface, long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001187 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001188
1189 // silently discard when control disabled
1190 // TODO: eventually migrate to be always enabled
1191 if (!mBandwidthControlEnabled) return;
1192
1193 // quick sanity check
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001194 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001195 throw new IllegalStateException("setting alert requires existing quota on iface");
1196 }
1197
1198 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001199 if (mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001200 throw new IllegalStateException("iface " + iface + " already has alert");
1201 }
1202
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001203 try {
1204 // TODO: support alert shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001205 mConnector.execute("bandwidth", "setinterfacealert", iface, alertBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001206 mActiveAlerts.put(iface, alertBytes);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001207 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001208 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001209 }
1210 }
1211 }
1212
1213 @Override
1214 public void removeInterfaceAlert(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001215 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001216
1217 // silently discard when control disabled
1218 // TODO: eventually migrate to be always enabled
1219 if (!mBandwidthControlEnabled) return;
1220
1221 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001222 if (!mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001223 // TODO: eventually consider throwing
1224 return;
1225 }
1226
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001227 try {
1228 // TODO: support alert shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001229 mConnector.execute("bandwidth", "removeinterfacealert", iface);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001230 mActiveAlerts.remove(iface);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001231 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001232 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001233 }
1234 }
1235 }
1236
1237 @Override
1238 public void setGlobalAlert(long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001239 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001240
1241 // silently discard when control disabled
1242 // TODO: eventually migrate to be always enabled
1243 if (!mBandwidthControlEnabled) return;
1244
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001245 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001246 mConnector.execute("bandwidth", "setglobalalert", alertBytes);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001247 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001248 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001249 }
1250 }
1251
1252 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001253 public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001254 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001255
Jeff Sharkey350083e2011-06-29 10:45:16 -07001256 // silently discard when control disabled
1257 // TODO: eventually migrate to be always enabled
1258 if (!mBandwidthControlEnabled) return;
1259
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001260 synchronized (mQuotaLock) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001261 final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
1262 if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
1263 // TODO: eventually consider throwing
1264 return;
1265 }
1266
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001267 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001268 mConnector.execute("bandwidth",
1269 rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001270 if (rejectOnQuotaInterfaces) {
1271 mUidRejectOnQuota.put(uid, true);
1272 } else {
1273 mUidRejectOnQuota.delete(uid);
1274 }
1275 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001276 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001277 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001278 }
1279 }
1280
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001281 @Override
1282 public boolean isBandwidthControlEnabled() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001283 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001284 return mBandwidthControlEnabled;
1285 }
1286
1287 @Override
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001288 public NetworkStats getNetworkStatsUidDetail(int uid) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001289 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001290 try {
1291 return mStatsFactory.readNetworkStatsDetail(uid);
1292 } catch (IOException e) {
1293 throw new IllegalStateException(e);
1294 }
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001295 }
1296
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001297 @Override
1298 public NetworkStats getNetworkStatsTethering(String[] ifacePairs) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001299 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001300
1301 if (ifacePairs.length % 2 != 0) {
1302 throw new IllegalArgumentException(
1303 "unexpected ifacePairs; length=" + ifacePairs.length);
1304 }
1305
1306 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
1307 for (int i = 0; i < ifacePairs.length; i += 2) {
1308 final String ifaceIn = ifacePairs[i];
1309 final String ifaceOut = ifacePairs[i + 1];
1310 if (ifaceIn != null && ifaceOut != null) {
1311 stats.combineValues(getNetworkStatsTethering(ifaceIn, ifaceOut));
1312 }
1313 }
1314 return stats;
1315 }
1316
1317 private NetworkStats.Entry getNetworkStatsTethering(String ifaceIn, String ifaceOut) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001318 final NativeDaemonEvent event;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001319 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001320 event = mConnector.execute("bandwidth", "gettetherstats", ifaceIn, ifaceOut);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001321 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001322 throw e.rethrowAsParcelableException();
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001323 }
1324
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001325 event.checkCode(TetheringStatsResult);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001326
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001327 // 221 ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
1328 final StringTokenizer tok = new StringTokenizer(event.getMessage());
1329 tok.nextToken();
1330 tok.nextToken();
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001331
1332 try {
1333 final NetworkStats.Entry entry = new NetworkStats.Entry();
1334 entry.iface = ifaceIn;
Jeff Sharkey905b5892011-09-30 15:19:49 -07001335 entry.uid = UID_TETHERING;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001336 entry.set = SET_DEFAULT;
1337 entry.tag = TAG_NONE;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001338 entry.rxBytes = Long.parseLong(tok.nextToken());
1339 entry.rxPackets = Long.parseLong(tok.nextToken());
1340 entry.txBytes = Long.parseLong(tok.nextToken());
1341 entry.txPackets = Long.parseLong(tok.nextToken());
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001342 return entry;
1343 } catch (NumberFormatException e) {
1344 throw new IllegalStateException(
1345 "problem parsing tethering stats for " + ifaceIn + " " + ifaceOut + ": " + e);
1346 }
1347 }
1348
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001349 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001350 public void setDefaultInterfaceForDns(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001351 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001352 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001353 mConnector.execute("resolver", "setdefaultif", iface);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001354 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001355 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001356 }
1357 }
1358
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001359 @Override
Robert Greenwalt8058f622012-11-09 10:52:27 -08001360 public void setDnsServersForInterface(String iface, String[] servers, String domains) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001361 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001362
Robert Greenwalt8058f622012-11-09 10:52:27 -08001363 final Command cmd = new Command("resolver", "setifdns", iface,
1364 (domains == null ? "" : domains));
1365
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001366 for (String s : servers) {
1367 InetAddress a = NetworkUtils.numericToInetAddress(s);
1368 if (a.isAnyLocalAddress() == false) {
1369 cmd.appendArg(a.getHostAddress());
Mattias Falk7475c0c2011-04-04 16:10:36 +02001370 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001371 }
1372
1373 try {
1374 mConnector.execute(cmd);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001375 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001376 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001377 }
1378 }
1379
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001380 @Override
Chad Brubaker3277620a2013-06-12 13:37:30 -07001381 public void setUidRangeRoute(String iface, int uid_start, int uid_end) {
1382 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1383 try {
1384 mConnector.execute("interface", "route",
1385 "uid", "add", iface, uid_start, uid_end);
1386 } catch (NativeDaemonConnectorException e) {
1387 throw e.rethrowAsParcelableException();
1388 }
1389 }
1390
1391 @Override
1392 public void clearUidRangeRoute(String iface, int uid_start, int uid_end) {
1393 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1394 try {
1395 mConnector.execute("interface", "route",
1396 "uid", "remove", iface, uid_start, uid_end);
1397 } catch (NativeDaemonConnectorException e) {
1398 throw e.rethrowAsParcelableException();
1399 }
1400 }
1401
1402 @Override
1403 public void setMarkedForwarding(String iface) {
1404 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1405 try {
1406 mConnector.execute("interface", "route", "fwmark", "add", iface);
1407 } catch (NativeDaemonConnectorException e) {
1408 throw e.rethrowAsParcelableException();
1409 }
1410 }
1411
1412 @Override
1413 public void clearMarkedForwarding(String iface) {
1414 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1415 try {
1416 mConnector.execute("interface", "route", "fwmark", "remove", iface);
1417 } catch (NativeDaemonConnectorException e) {
1418 throw e.rethrowAsParcelableException();
1419 }
1420 }
1421
1422 @Override
1423 public void setDnsInterfaceForUidRange(String iface, int uid_start, int uid_end) {
1424 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1425 try {
1426 mConnector.execute("resolver", "setifaceforuidrange", iface, uid_start, uid_end);
1427 } catch (NativeDaemonConnectorException e) {
1428 throw e.rethrowAsParcelableException();
1429 }
1430 }
1431
1432 @Override
1433 public void clearDnsInterfaceForUidRange(int uid_start, int uid_end) {
1434 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1435 try {
1436 mConnector.execute("resolver", "clearifaceforuidrange", uid_start, uid_end);
1437 } catch (NativeDaemonConnectorException e) {
1438 throw e.rethrowAsParcelableException();
1439 }
1440 }
1441
1442 @Override
1443 public void clearDnsInterfaceMaps() {
1444 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1445 try {
1446 mConnector.execute("resolver", "clearifacemapping");
1447 } catch (NativeDaemonConnectorException e) {
1448 throw e.rethrowAsParcelableException();
1449 }
1450 }
1451
1452
1453 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001454 public void flushDefaultDnsCache() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001455 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001456 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001457 mConnector.execute("resolver", "flushdefaultif");
Mattias Falk7475c0c2011-04-04 16:10:36 +02001458 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001459 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001460 }
1461 }
1462
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001463 @Override
1464 public void flushInterfaceDnsCache(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001465 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001466 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001467 mConnector.execute("resolver", "flushif", iface);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001468 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001469 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001470 }
1471 }
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -07001472
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001473 @Override
1474 public void setFirewallEnabled(boolean enabled) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001475 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001476 try {
1477 mConnector.execute("firewall", enabled ? "enable" : "disable");
1478 mFirewallEnabled = enabled;
1479 } catch (NativeDaemonConnectorException e) {
1480 throw e.rethrowAsParcelableException();
1481 }
1482 }
1483
1484 @Override
1485 public boolean isFirewallEnabled() {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001486 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001487 return mFirewallEnabled;
1488 }
1489
1490 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001491 public void setFirewallInterfaceRule(String iface, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001492 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001493 Preconditions.checkState(mFirewallEnabled);
1494 final String rule = allow ? ALLOW : DENY;
1495 try {
1496 mConnector.execute("firewall", "set_interface_rule", iface, rule);
1497 } catch (NativeDaemonConnectorException e) {
1498 throw e.rethrowAsParcelableException();
1499 }
1500 }
1501
1502 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001503 public void setFirewallEgressSourceRule(String addr, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001504 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001505 Preconditions.checkState(mFirewallEnabled);
1506 final String rule = allow ? ALLOW : DENY;
1507 try {
1508 mConnector.execute("firewall", "set_egress_source_rule", addr, rule);
1509 } catch (NativeDaemonConnectorException e) {
1510 throw e.rethrowAsParcelableException();
1511 }
1512 }
1513
1514 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001515 public void setFirewallEgressDestRule(String addr, int port, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001516 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001517 Preconditions.checkState(mFirewallEnabled);
1518 final String rule = allow ? ALLOW : DENY;
1519 try {
1520 mConnector.execute("firewall", "set_egress_dest_rule", addr, port, rule);
1521 } catch (NativeDaemonConnectorException e) {
1522 throw e.rethrowAsParcelableException();
1523 }
1524 }
1525
1526 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001527 public void setFirewallUidRule(int uid, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001528 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001529 Preconditions.checkState(mFirewallEnabled);
1530 final String rule = allow ? ALLOW : DENY;
1531 try {
1532 mConnector.execute("firewall", "set_uid_rule", uid, rule);
1533 } catch (NativeDaemonConnectorException e) {
1534 throw e.rethrowAsParcelableException();
1535 }
1536 }
1537
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001538 private static void enforceSystemUid() {
1539 final int uid = Binder.getCallingUid();
1540 if (uid != Process.SYSTEM_UID) {
1541 throw new SecurityException("Only available to AID_SYSTEM");
1542 }
1543 }
1544
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001545 @Override
Mattias Falk8b47b362011-08-23 14:15:13 +02001546 public void setDnsInterfaceForPid(String iface, int pid) throws IllegalStateException {
1547 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1548 try {
Jeff Sharkey0c232f52013-02-13 11:27:24 -08001549 mConnector.execute("resolver", "setifaceforpid", iface, pid);
Mattias Falk8b47b362011-08-23 14:15:13 +02001550 } catch (NativeDaemonConnectorException e) {
1551 throw new IllegalStateException(
1552 "Error communicating with native deamon to set interface for pid" + iface, e);
1553 }
1554 }
1555
1556 @Override
1557 public void clearDnsInterfaceForPid(int pid) throws IllegalStateException {
1558 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1559 try {
Jeff Sharkey0c232f52013-02-13 11:27:24 -08001560 mConnector.execute("resolver", "clearifaceforpid", pid);
Mattias Falk8b47b362011-08-23 14:15:13 +02001561 } catch (NativeDaemonConnectorException e) {
1562 throw new IllegalStateException(
1563 "Error communicating with native deamon to clear interface for pid " + pid, e);
1564 }
1565 }
1566
Lorenzo Colitti79751842013-02-28 16:16:03 +09001567 @Override
1568 public void startClatd(String interfaceName) throws IllegalStateException {
1569 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1570
1571 try {
1572 mConnector.execute("clatd", "start", interfaceName);
1573 } catch (NativeDaemonConnectorException e) {
1574 throw e.rethrowAsParcelableException();
1575 }
1576 }
1577
1578 @Override
1579 public void stopClatd() throws IllegalStateException {
1580 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1581
1582 try {
1583 mConnector.execute("clatd", "stop");
1584 } catch (NativeDaemonConnectorException e) {
1585 throw e.rethrowAsParcelableException();
1586 }
1587 }
1588
1589 @Override
1590 public boolean isClatdStarted() {
1591 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1592
1593 final NativeDaemonEvent event;
1594 try {
1595 event = mConnector.execute("clatd", "status");
1596 } catch (NativeDaemonConnectorException e) {
1597 throw e.rethrowAsParcelableException();
1598 }
1599
1600 event.checkCode(ClatdStatusResult);
1601 return event.getMessage().endsWith("started");
1602 }
1603
Mattias Falk8b47b362011-08-23 14:15:13 +02001604 /** {@inheritDoc} */
Jeff Sharkey7b4596f2013-02-25 10:55:29 -08001605 @Override
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -07001606 public void monitor() {
1607 if (mConnector != null) {
1608 mConnector.monitor();
1609 }
1610 }
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001611
1612 @Override
1613 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1614 mContext.enforceCallingOrSelfPermission(DUMP, TAG);
1615
Robert Greenwalt470fd722012-01-18 12:51:15 -08001616 pw.println("NetworkManagementService NativeDaemonConnector Log:");
1617 mConnector.dump(fd, pw, args);
1618 pw.println();
1619
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001620 pw.print("Bandwidth control enabled: "); pw.println(mBandwidthControlEnabled);
1621
1622 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001623 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
1624 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001625 }
1626
1627 synchronized (mUidRejectOnQuota) {
1628 pw.print("UID reject on quota ifaces: [");
1629 final int size = mUidRejectOnQuota.size();
1630 for (int i = 0; i < size; i++) {
1631 pw.print(mUidRejectOnQuota.keyAt(i));
1632 if (i < size - 1) pw.print(",");
1633 }
1634 pw.println("]");
1635 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001636
1637 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001638 }
San Mehat873f2142010-01-14 10:25:07 -08001639}