blob: ad7ec99775a316edd7e38ba76670420041eae529 [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 Sharkeye4984be2013-09-10 21:03:27 -070027import static com.android.server.NetworkManagementService.NetdResponseCode.GetMarkResult;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080028import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
29import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080030import static com.android.server.NetworkManagementService.NetdResponseCode.IpFwdStatusResult;
31import static com.android.server.NetworkManagementService.NetdResponseCode.TetherDnsFwdTgtListResult;
32import static com.android.server.NetworkManagementService.NetdResponseCode.TetherInterfaceListResult;
33import static com.android.server.NetworkManagementService.NetdResponseCode.TetherStatusResult;
Jeff Sharkeye4984be2013-09-10 21:03:27 -070034import static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsListResult;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080035import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
Jeff Sharkeya63ba592011-07-19 23:47:12 -070036import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070037
San Mehat873f2142010-01-14 10:25:07 -080038import android.content.Context;
San Mehat4d02d002010-01-22 16:07:46 -080039import android.net.INetworkManagementEventObserver;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070040import android.net.InterfaceConfiguration;
Robert Greenwalted126402011-01-28 15:34:55 -080041import android.net.LinkAddress;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070042import android.net.NetworkStats;
Robert Greenwalted126402011-01-28 15:34:55 -080043import android.net.NetworkUtils;
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070044import android.net.RouteInfo;
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -080045import android.net.wifi.WifiConfiguration;
46import android.net.wifi.WifiConfiguration.KeyMgmt;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070047import android.os.BatteryStats;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070048import android.os.Binder;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070049import android.os.Handler;
San Mehat873f2142010-01-14 10:25:07 -080050import android.os.INetworkManagementService;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070051import android.os.Process;
Jeff Sharkey3df273e2011-12-15 15:47:12 -080052import android.os.RemoteCallbackList;
53import android.os.RemoteException;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070054import android.os.ServiceManager;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070055import android.os.SystemClock;
Marco Nelissen62dbb222010-02-18 10:56:30 -080056import android.os.SystemProperties;
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -080057import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080058import android.util.Slog;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -070059import android.util.SparseBooleanArray;
San Mehat873f2142010-01-14 10:25:07 -080060
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070061import com.android.internal.app.IBatteryStats;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070062import com.android.internal.net.NetworkStatsFactory;
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070063import com.android.internal.util.Preconditions;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080064import com.android.server.NativeDaemonConnector.Command;
Jeff Sharkey56cd6462013-06-07 15:09:15 -070065import com.android.server.NativeDaemonConnector.SensitiveArg;
Jeff Sharkey69ddab42012-08-25 00:05:46 -070066import com.android.server.net.LockdownVpnTracker;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070067import com.google.android.collect.Maps;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070068
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070069import java.io.BufferedReader;
70import java.io.DataInputStream;
San Mehat873f2142010-01-14 10:25:07 -080071import java.io.File;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070072import java.io.FileDescriptor;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070073import java.io.FileInputStream;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070074import java.io.IOException;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070075import java.io.InputStreamReader;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070076import java.io.PrintWriter;
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070077import java.net.Inet4Address;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070078import java.net.InetAddress;
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -070079import java.net.InterfaceAddress;
80import java.net.NetworkInterface;
81import java.net.SocketException;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070082import java.util.ArrayList;
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -070083import java.util.Collection;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070084import java.util.HashMap;
85import java.util.Map;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070086import java.util.NoSuchElementException;
87import java.util.StringTokenizer;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -070088import java.util.concurrent.CountDownLatch;
San Mehat873f2142010-01-14 10:25:07 -080089
90/**
91 * @hide
92 */
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070093public class NetworkManagementService extends INetworkManagementService.Stub
94 implements Watchdog.Monitor {
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070095 private static final String TAG = "NetworkManagementService";
Dianne Hackborncef65ee2010-09-30 18:27:22 -070096 private static final boolean DBG = false;
Kenny Root305bcbf2010-09-03 07:56:38 -070097 private static final String NETD_TAG = "NetdConnector";
Lorenzo Colitti7421a012013-08-20 22:51:24 +090098 private static final String NETD_SOCKET_NAME = "netd";
Kenny Root305bcbf2010-09-03 07:56:38 -070099
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800100 private static final String ADD = "add";
101 private static final String REMOVE = "remove";
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700102
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700103 private static final String ALLOW = "allow";
104 private static final String DENY = "deny";
105
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700106 private static final String DEFAULT = "default";
107 private static final String SECONDARY = "secondary";
108
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700109 /**
110 * Name representing {@link #setGlobalAlert(long)} limit when delivered to
111 * {@link INetworkManagementEventObserver#limitReached(String, String)}.
112 */
113 public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
114
San Mehat873f2142010-01-14 10:25:07 -0800115 class NetdResponseCode {
JP Abgrall12b933d2011-07-14 18:09:22 -0700116 /* Keep in sync with system/netd/ResponseCode.h */
San Mehat873f2142010-01-14 10:25:07 -0800117 public static final int InterfaceListResult = 110;
118 public static final int TetherInterfaceListResult = 111;
119 public static final int TetherDnsFwdTgtListResult = 112;
San Mehat72759df2010-01-19 13:50:37 -0800120 public static final int TtyListResult = 113;
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700121 public static final int TetheringStatsListResult = 114;
San Mehat873f2142010-01-14 10:25:07 -0800122
123 public static final int TetherStatusResult = 210;
124 public static final int IpFwdStatusResult = 211;
San Mehated4fc8a2010-01-22 12:28:36 -0800125 public static final int InterfaceGetCfgResult = 213;
Robert Greenwalte3253922010-02-18 09:23:25 -0800126 public static final int SoftapStatusResult = 214;
San Mehat91cac642010-03-31 14:31:36 -0700127 public static final int InterfaceRxCounterResult = 216;
128 public static final int InterfaceTxCounterResult = 217;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700129 public static final int QuotaCounterResult = 220;
130 public static final int TetheringStatsResult = 221;
Selim Gurun84c00c62012-02-27 15:42:38 -0800131 public static final int DnsProxyQueryResult = 222;
Lorenzo Colitti79751842013-02-28 16:16:03 +0900132 public static final int ClatdStatusResult = 223;
Chad Brubakercca54c42013-06-27 17:41:38 -0700133 public static final int GetMarkResult = 225;
Robert Greenwalte3253922010-02-18 09:23:25 -0800134
135 public static final int InterfaceChange = 600;
JP Abgrall12b933d2011-07-14 18:09:22 -0700136 public static final int BandwidthControl = 601;
Haoyu Bai6b7358d2012-07-17 16:36:50 -0700137 public static final int InterfaceClassActivity = 613;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900138 public static final int InterfaceAddressChange = 614;
Lorenzo Colitti5ae4a532013-10-31 11:59:46 +0900139 public static final int InterfaceDnsServerInfo = 615;
San Mehat873f2142010-01-14 10:25:07 -0800140 }
141
142 /**
143 * Binder context for this service
144 */
145 private Context mContext;
146
147 /**
148 * connector object for communicating with netd
149 */
150 private NativeDaemonConnector mConnector;
151
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700152 private final Handler mMainHandler = new Handler();
153
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700154 private Thread mThread;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700155 private CountDownLatch mConnectedSignal = new CountDownLatch(1);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700156
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800157 private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
158 new RemoteCallbackList<INetworkManagementEventObserver>();
San Mehat4d02d002010-01-22 16:07:46 -0800159
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700160 private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
161
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700162 private Object mQuotaLock = new Object();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700163 /** Set of interfaces with active quotas. */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700164 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700165 /** Set of interfaces with active alerts. */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700166 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700167 /** Set of UIDs with active reject rules. */
168 private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
169
Haoyu Bai04124232012-06-28 15:26:19 -0700170 private Object mIdleTimerLock = new Object();
171 /** Set of interfaces with active idle timers. */
172 private static class IdleTimerParams {
173 public final int timeout;
174 public final String label;
175 public int networkCount;
176
177 IdleTimerParams(int timeout, String label) {
178 this.timeout = timeout;
179 this.label = label;
180 this.networkCount = 1;
181 }
182 }
183 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
184
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700185 private volatile boolean mBandwidthControlEnabled;
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700186 private volatile boolean mFirewallEnabled;
Jeff Sharkey350083e2011-06-29 10:45:16 -0700187
San Mehat873f2142010-01-14 10:25:07 -0800188 /**
189 * Constructs a new NetworkManagementService instance
190 *
191 * @param context Binder context for this service
192 */
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900193 private NetworkManagementService(Context context, String socket) {
San Mehat873f2142010-01-14 10:25:07 -0800194 mContext = context;
San Mehat4d02d002010-01-22 16:07:46 -0800195
Marco Nelissen62dbb222010-02-18 10:56:30 -0800196 if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
197 return;
198 }
199
San Mehat873f2142010-01-14 10:25:07 -0800200 mConnector = new NativeDaemonConnector(
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900201 new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700202 mThread = new Thread(mConnector, NETD_TAG);
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700203
204 // Add ourself to the Watchdog monitors.
205 Watchdog.getInstance().addMonitor(this);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700206 }
207
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900208 static NetworkManagementService create(Context context,
209 String socket) throws InterruptedException {
210 final NetworkManagementService service = new NetworkManagementService(context, socket);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700211 final CountDownLatch connectedSignal = service.mConnectedSignal;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700212 if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
213 service.mThread.start();
214 if (DBG) Slog.d(TAG, "Awaiting socket connection");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700215 connectedSignal.await();
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700216 if (DBG) Slog.d(TAG, "Connected");
217 return service;
San Mehat873f2142010-01-14 10:25:07 -0800218 }
219
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900220 public static NetworkManagementService create(Context context) throws InterruptedException {
221 return create(context, NETD_SOCKET_NAME);
222 }
223
Jeff Sharkey350083e2011-06-29 10:45:16 -0700224 public void systemReady() {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700225 prepareNativeDaemon();
226 if (DBG) Slog.d(TAG, "Prepared");
Jeff Sharkey350083e2011-06-29 10:45:16 -0700227 }
228
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800229 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800230 public void registerObserver(INetworkManagementEventObserver observer) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800231 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800232 mObservers.register(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800233 }
234
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800235 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800236 public void unregisterObserver(INetworkManagementEventObserver observer) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800237 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800238 mObservers.unregister(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800239 }
240
241 /**
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700242 * Notify our observers of an interface status change
San Mehat4d02d002010-01-22 16:07:46 -0800243 */
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700244 private void notifyInterfaceStatusChanged(String iface, boolean up) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800245 final int length = mObservers.beginBroadcast();
246 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800247 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800248 mObservers.getBroadcastItem(i).interfaceStatusChanged(iface, up);
249 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900250 } catch (RuntimeException e) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700251 }
252 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800253 mObservers.finishBroadcast();
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700254 }
255
256 /**
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700257 * Notify our observers of an interface link state change
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700258 * (typically, an Ethernet cable has been plugged-in or unplugged).
259 */
260 private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800261 final int length = mObservers.beginBroadcast();
262 for (int i = 0; i < length; i++) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700263 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800264 mObservers.getBroadcastItem(i).interfaceLinkStateChanged(iface, up);
265 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900266 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800267 }
268 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800269 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800270 }
271
272 /**
273 * Notify our observers of an interface addition.
274 */
275 private void notifyInterfaceAdded(String iface) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800276 final int length = mObservers.beginBroadcast();
277 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800278 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800279 mObservers.getBroadcastItem(i).interfaceAdded(iface);
280 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900281 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800282 }
283 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800284 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800285 }
286
287 /**
288 * Notify our observers of an interface removal.
289 */
290 private void notifyInterfaceRemoved(String iface) {
Jeff Sharkey89b8a212011-10-11 11:58:11 -0700291 // netd already clears out quota and alerts for removed ifaces; update
292 // our sanity-checking state.
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700293 mActiveAlerts.remove(iface);
294 mActiveQuotas.remove(iface);
Jeff Sharkey89b8a212011-10-11 11:58:11 -0700295
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800296 final int length = mObservers.beginBroadcast();
297 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800298 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800299 mObservers.getBroadcastItem(i).interfaceRemoved(iface);
300 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900301 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800302 }
303 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800304 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800305 }
306
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700307 /**
JP Abgrall12b933d2011-07-14 18:09:22 -0700308 * Notify our observers of a limit reached.
309 */
310 private void notifyLimitReached(String limitName, String iface) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800311 final int length = mObservers.beginBroadcast();
312 for (int i = 0; i < length; i++) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700313 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800314 mObservers.getBroadcastItem(i).limitReached(limitName, iface);
315 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900316 } catch (RuntimeException e) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700317 }
318 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800319 mObservers.finishBroadcast();
JP Abgrall12b933d2011-07-14 18:09:22 -0700320 }
321
322 /**
Haoyu Baidb3c8672012-06-20 14:29:57 -0700323 * Notify our observers of a change in the data activity state of the interface
324 */
325 private void notifyInterfaceClassActivity(String label, boolean active) {
326 final int length = mObservers.beginBroadcast();
327 for (int i = 0; i < length; i++) {
328 try {
329 mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(label, active);
330 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900331 } catch (RuntimeException e) {
Haoyu Baidb3c8672012-06-20 14:29:57 -0700332 }
333 }
334 mObservers.finishBroadcast();
335 }
336
337 /**
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700338 * Prepare native daemon once connected, enabling modules and pushing any
339 * existing in-memory rules.
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700340 */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700341 private void prepareNativeDaemon() {
342 mBandwidthControlEnabled = false;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700343
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700344 // only enable bandwidth control when support exists
345 final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists();
346 if (hasKernelSupport) {
347 Slog.d(TAG, "enabling bandwidth control");
348 try {
349 mConnector.execute("bandwidth", "enable");
350 mBandwidthControlEnabled = true;
351 } catch (NativeDaemonConnectorException e) {
352 Log.wtf(TAG, "problem enabling bandwidth controls", e);
353 }
354 } else {
355 Slog.d(TAG, "not enabling bandwidth control");
356 }
357
358 SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0");
359
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700360 if (mBandwidthControlEnabled) {
361 try {
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700362 IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME))
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700363 .noteNetworkStatsEnabled();
364 } catch (RemoteException e) {
365 }
366 }
367
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700368 // push any existing quota or UID rules
369 synchronized (mQuotaLock) {
370 int size = mActiveQuotas.size();
371 if (size > 0) {
372 Slog.d(TAG, "pushing " + size + " active quota rules");
373 final HashMap<String, Long> activeQuotas = mActiveQuotas;
374 mActiveQuotas = Maps.newHashMap();
375 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
376 setInterfaceQuota(entry.getKey(), entry.getValue());
377 }
378 }
379
380 size = mActiveAlerts.size();
381 if (size > 0) {
382 Slog.d(TAG, "pushing " + size + " active alert rules");
383 final HashMap<String, Long> activeAlerts = mActiveAlerts;
384 mActiveAlerts = Maps.newHashMap();
385 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
386 setInterfaceAlert(entry.getKey(), entry.getValue());
387 }
388 }
389
390 size = mUidRejectOnQuota.size();
391 if (size > 0) {
392 Slog.d(TAG, "pushing " + size + " active uid rules");
393 final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota;
394 mUidRejectOnQuota = new SparseBooleanArray();
395 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
396 setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i));
397 }
398 }
399 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700400
401 // TODO: Push any existing firewall state
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700402 setFirewallEnabled(mFirewallEnabled || LockdownVpnTracker.isEnabled());
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700403 }
San Mehat4d02d002010-01-22 16:07:46 -0800404
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900405 /**
406 * Notify our observers of a new or updated interface address.
407 */
Lorenzo Colitti64483942013-11-15 18:43:52 +0900408 private void notifyAddressUpdated(String iface, LinkAddress address) {
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900409 final int length = mObservers.beginBroadcast();
410 for (int i = 0; i < length; i++) {
411 try {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900412 mObservers.getBroadcastItem(i).addressUpdated(iface, address);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900413 } catch (RemoteException e) {
414 } catch (RuntimeException e) {
415 }
416 }
417 mObservers.finishBroadcast();
418 }
419
420 /**
421 * Notify our observers of a deleted interface address.
422 */
Lorenzo Colitti64483942013-11-15 18:43:52 +0900423 private void notifyAddressRemoved(String iface, LinkAddress address) {
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900424 final int length = mObservers.beginBroadcast();
425 for (int i = 0; i < length; i++) {
426 try {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900427 mObservers.getBroadcastItem(i).addressRemoved(iface, address);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900428 } catch (RemoteException e) {
429 } catch (RuntimeException e) {
430 }
431 }
432 mObservers.finishBroadcast();
433 }
434
Lorenzo Colitti5ae4a532013-10-31 11:59:46 +0900435 /**
436 * Notify our observers of DNS server information received.
437 */
438 private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
439 final int length = mObservers.beginBroadcast();
440 for (int i = 0; i < length; i++) {
441 try {
442 mObservers.getBroadcastItem(i).interfaceDnsServerInfo(iface, lifetime, addresses);
443 } catch (RemoteException e) {
444 } catch (RuntimeException e) {
445 }
446 }
447 mObservers.finishBroadcast();
448 }
449
San Mehat873f2142010-01-14 10:25:07 -0800450 //
451 // Netd Callback handling
452 //
453
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700454 private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks {
455 @Override
San Mehat873f2142010-01-14 10:25:07 -0800456 public void onDaemonConnected() {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700457 // event is dispatched from internal NDC thread, so we prepare the
458 // daemon back on main thread.
459 if (mConnectedSignal != null) {
460 mConnectedSignal.countDown();
461 mConnectedSignal = null;
462 } else {
463 mMainHandler.post(new Runnable() {
464 @Override
465 public void run() {
466 prepareNativeDaemon();
467 }
468 });
469 }
San Mehat873f2142010-01-14 10:25:07 -0800470 }
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700471
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700472 @Override
San Mehat873f2142010-01-14 10:25:07 -0800473 public boolean onEvent(int code, String raw, String[] cooked) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900474 String errorMessage = String.format("Invalid event from daemon (%s)", raw);
JP Abgrall12b933d2011-07-14 18:09:22 -0700475 switch (code) {
476 case NetdResponseCode.InterfaceChange:
477 /*
478 * a network interface change occured
479 * Format: "NNN Iface added <name>"
480 * "NNN Iface removed <name>"
481 * "NNN Iface changed <name> <up/down>"
482 * "NNN Iface linkstatus <name> <up/down>"
483 */
484 if (cooked.length < 4 || !cooked[1].equals("Iface")) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900485 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700486 }
487 if (cooked[2].equals("added")) {
488 notifyInterfaceAdded(cooked[3]);
489 return true;
490 } else if (cooked[2].equals("removed")) {
491 notifyInterfaceRemoved(cooked[3]);
492 return true;
493 } else if (cooked[2].equals("changed") && cooked.length == 5) {
494 notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
495 return true;
496 } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
497 notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
498 return true;
499 }
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900500 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700501 // break;
502 case NetdResponseCode.BandwidthControl:
503 /*
504 * Bandwidth control needs some attention
505 * Format: "NNN limit alert <alertName> <ifaceName>"
506 */
507 if (cooked.length < 5 || !cooked[1].equals("limit")) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900508 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700509 }
510 if (cooked[2].equals("alert")) {
511 notifyLimitReached(cooked[3], cooked[4]);
512 return true;
513 }
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900514 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700515 // break;
Haoyu Baidb3c8672012-06-20 14:29:57 -0700516 case NetdResponseCode.InterfaceClassActivity:
517 /*
518 * An network interface class state changed (active/idle)
519 * Format: "NNN IfaceClass <active/idle> <label>"
520 */
521 if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900522 throw new IllegalStateException(errorMessage);
Haoyu Baidb3c8672012-06-20 14:29:57 -0700523 }
524 boolean isActive = cooked[2].equals("active");
525 notifyInterfaceClassActivity(cooked[3], isActive);
526 return true;
527 // break;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900528 case NetdResponseCode.InterfaceAddressChange:
529 /*
530 * A network address change occurred
531 * Format: "NNN Address updated <addr> <iface> <flags> <scope>"
532 * "NNN Address removed <addr> <iface> <flags> <scope>"
533 */
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900534 if (cooked.length < 7 || !cooked[1].equals("Address")) {
535 throw new IllegalStateException(errorMessage);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900536 }
537
Lorenzo Colitti64483942013-11-15 18:43:52 +0900538 String iface = cooked[4];
Lorenzo Colitti5ad421a2013-11-17 15:05:02 +0900539 LinkAddress address;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900540 try {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900541 int flags = Integer.parseInt(cooked[5]);
542 int scope = Integer.parseInt(cooked[6]);
543 address = new LinkAddress(cooked[3], flags, scope);
Lorenzo Colitti5ad421a2013-11-17 15:05:02 +0900544 } catch(NumberFormatException e) { // Non-numeric lifetime or scope.
545 throw new IllegalStateException(errorMessage, e);
Lorenzo Colitti64483942013-11-15 18:43:52 +0900546 } catch(IllegalArgumentException e) { // Malformed/invalid IP address.
Lorenzo Colitti5ad421a2013-11-17 15:05:02 +0900547 throw new IllegalStateException(errorMessage, e);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900548 }
549
550 if (cooked[2].equals("updated")) {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900551 notifyAddressUpdated(iface, address);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900552 } else {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900553 notifyAddressRemoved(iface, address);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900554 }
555 return true;
556 // break;
Lorenzo Colitti5ae4a532013-10-31 11:59:46 +0900557 case NetdResponseCode.InterfaceDnsServerInfo:
558 /*
559 * Information about available DNS servers has been received.
560 * Format: "NNN DnsInfo servers <interface> <lifetime> <servers>"
561 */
562 long lifetime; // Actually a 32-bit unsigned integer.
563
564 if (cooked.length == 6 &&
565 cooked[1].equals("DnsInfo") &&
566 cooked[2].equals("servers")) {
567 try {
568 lifetime = Long.parseLong(cooked[4]);
569 } catch (NumberFormatException e) {
570 throw new IllegalStateException(errorMessage);
571 }
572 String[] servers = cooked[5].split(",");
573 notifyInterfaceDnsServerInfo(cooked[3], lifetime, servers);
574 }
575 return true;
576 // break;
JP Abgrall12b933d2011-07-14 18:09:22 -0700577 default: break;
Robert Greenwalte3253922010-02-18 09:23:25 -0800578 }
579 return false;
San Mehat873f2142010-01-14 10:25:07 -0800580 }
581 }
582
San Mehated4fc8a2010-01-22 12:28:36 -0800583
San Mehat873f2142010-01-14 10:25:07 -0800584 //
585 // INetworkManagementService members
586 //
587
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800588 @Override
589 public String[] listInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800590 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700591 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800592 return NativeDaemonEvent.filterMessageList(
593 mConnector.executeForList("interface", "list"), InterfaceListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700594 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800595 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700596 }
San Mehated4fc8a2010-01-22 12:28:36 -0800597 }
598
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800599 @Override
600 public InterfaceConfiguration getInterfaceConfig(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800601 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800602
603 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700604 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800605 event = mConnector.execute("interface", "getcfg", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700606 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800607 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700608 }
San Mehated4fc8a2010-01-22 12:28:36 -0800609
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800610 event.checkCode(InterfaceGetCfgResult);
611
612 // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz flag1 flag2 flag3
613 final StringTokenizer st = new StringTokenizer(event.getMessage());
San Mehated4fc8a2010-01-22 12:28:36 -0800614
Kenny Roota80ce062010-06-01 13:23:53 -0700615 InterfaceConfiguration cfg;
San Mehated4fc8a2010-01-22 12:28:36 -0800616 try {
Kenny Roota80ce062010-06-01 13:23:53 -0700617 cfg = new InterfaceConfiguration();
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800618 cfg.setHardwareAddress(st.nextToken(" "));
Robert Greenwalted126402011-01-28 15:34:55 -0800619 InetAddress addr = null;
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800620 int prefixLength = 0;
Kenny Roota80ce062010-06-01 13:23:53 -0700621 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800622 addr = NetworkUtils.numericToInetAddress(st.nextToken());
Robert Greenwalte5903732011-02-22 16:00:42 -0800623 } catch (IllegalArgumentException iae) {
624 Slog.e(TAG, "Failed to parse ipaddr", iae);
Kenny Roota80ce062010-06-01 13:23:53 -0700625 }
626
627 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800628 prefixLength = Integer.parseInt(st.nextToken());
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800629 } catch (NumberFormatException nfe) {
630 Slog.e(TAG, "Failed to parse prefixLength", nfe);
Kenny Roota80ce062010-06-01 13:23:53 -0700631 }
Robert Greenwalt04808c22010-12-13 17:01:41 -0800632
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800633 cfg.setLinkAddress(new LinkAddress(addr, prefixLength));
634 while (st.hasMoreTokens()) {
635 cfg.setFlag(st.nextToken());
636 }
Kenny Roota80ce062010-06-01 13:23:53 -0700637 } catch (NoSuchElementException nsee) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800638 throw new IllegalStateException("Invalid response from daemon: " + event);
San Mehated4fc8a2010-01-22 12:28:36 -0800639 }
San Mehated4fc8a2010-01-22 12:28:36 -0800640 return cfg;
641 }
642
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800643 @Override
644 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800645 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800646 LinkAddress linkAddr = cfg.getLinkAddress();
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800647 if (linkAddr == null || linkAddr.getAddress() == null) {
648 throw new IllegalStateException("Null LinkAddress given");
Robert Greenwalted126402011-01-28 15:34:55 -0800649 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800650
651 final Command cmd = new Command("interface", "setcfg", iface,
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800652 linkAddr.getAddress().getHostAddress(),
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800653 linkAddr.getNetworkPrefixLength());
654 for (String flag : cfg.getFlags()) {
655 cmd.appendArg(flag);
656 }
657
Kenny Roota80ce062010-06-01 13:23:53 -0700658 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800659 mConnector.execute(cmd);
Kenny Roota80ce062010-06-01 13:23:53 -0700660 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800661 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700662 }
San Mehat873f2142010-01-14 10:25:07 -0800663 }
664
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800665 @Override
666 public void setInterfaceDown(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800667 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800668 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800669 ifcg.setInterfaceDown();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800670 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700671 }
672
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800673 @Override
674 public void setInterfaceUp(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800675 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800676 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800677 ifcg.setInterfaceUp();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800678 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700679 }
680
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800681 @Override
682 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800683 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sheriff73293612011-09-14 12:31:56 -0700684 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800685 mConnector.execute(
686 "interface", "ipv6privacyextensions", iface, enable ? "enable" : "disable");
Irfan Sheriff73293612011-09-14 12:31:56 -0700687 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800688 throw e.rethrowAsParcelableException();
Irfan Sheriff73293612011-09-14 12:31:56 -0700689 }
690 }
691
Irfan Sherifff5600612011-06-16 10:26:28 -0700692 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
693 IPv6 addresses on interface down, but we need to do full clean up here */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800694 @Override
695 public void clearInterfaceAddresses(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800696 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sherifff5600612011-06-16 10:26:28 -0700697 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800698 mConnector.execute("interface", "clearaddrs", iface);
Irfan Sherifff5600612011-06-16 10:26:28 -0700699 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800700 throw e.rethrowAsParcelableException();
Irfan Sherifff5600612011-06-16 10:26:28 -0700701 }
702 }
703
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800704 @Override
705 public void enableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800706 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700707 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800708 mConnector.execute("interface", "ipv6", iface, "enable");
repo sync7960d9f2011-09-29 12:40:02 -0700709 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800710 throw e.rethrowAsParcelableException();
repo sync7960d9f2011-09-29 12:40:02 -0700711 }
712 }
713
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800714 @Override
715 public void disableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800716 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700717 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800718 mConnector.execute("interface", "ipv6", iface, "disable");
repo sync7960d9f2011-09-29 12:40:02 -0700719 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800720 throw e.rethrowAsParcelableException();
repo sync7960d9f2011-09-29 12:40:02 -0700721 }
722 }
723
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800724 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700725 public void addRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800726 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700727 modifyRoute(interfaceName, ADD, route, DEFAULT);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700728 }
729
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800730 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700731 public void removeRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800732 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700733 modifyRoute(interfaceName, REMOVE, route, DEFAULT);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700734 }
735
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800736 @Override
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700737 public void addSecondaryRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800738 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700739 modifyRoute(interfaceName, ADD, route, SECONDARY);
740 }
741
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800742 @Override
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700743 public void removeSecondaryRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800744 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700745 modifyRoute(interfaceName, REMOVE, route, SECONDARY);
746 }
747
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800748 private void modifyRoute(String interfaceName, String action, RouteInfo route, String type) {
749 final Command cmd = new Command("interface", "route", action, interfaceName, type);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700750
751 // create triplet: dest-ip-addr prefixlength gateway-ip-addr
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800752 final LinkAddress la = route.getDestination();
753 cmd.appendArg(la.getAddress().getHostAddress());
754 cmd.appendArg(la.getNetworkPrefixLength());
755
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700756 if (route.getGateway() == null) {
757 if (la.getAddress() instanceof Inet4Address) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800758 cmd.appendArg("0.0.0.0");
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700759 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800760 cmd.appendArg("::0");
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700761 }
762 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800763 cmd.appendArg(route.getGateway().getHostAddress());
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700764 }
765
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800766 try {
767 mConnector.execute(cmd);
768 } catch (NativeDaemonConnectorException e) {
769 throw e.rethrowAsParcelableException();
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700770 }
771 }
772
773 private ArrayList<String> readRouteList(String filename) {
774 FileInputStream fstream = null;
775 ArrayList<String> list = new ArrayList<String>();
776
777 try {
778 fstream = new FileInputStream(filename);
779 DataInputStream in = new DataInputStream(fstream);
780 BufferedReader br = new BufferedReader(new InputStreamReader(in));
781 String s;
782
783 // throw away the title line
784
785 while (((s = br.readLine()) != null) && (s.length() != 0)) {
786 list.add(s);
787 }
788 } catch (IOException ex) {
789 // return current list, possibly empty
790 } finally {
791 if (fstream != null) {
792 try {
793 fstream.close();
794 } catch (IOException ex) {}
795 }
796 }
797
798 return list;
799 }
800
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800801 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700802 public RouteInfo[] getRoutes(String interfaceName) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800803 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700804 ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
805
806 // v4 routes listed as:
807 // iface dest-addr gateway-addr flags refcnt use metric netmask mtu window IRTT
808 for (String s : readRouteList("/proc/net/route")) {
809 String[] fields = s.split("\t");
810
811 if (fields.length > 7) {
812 String iface = fields[0];
813
814 if (interfaceName.equals(iface)) {
815 String dest = fields[1];
816 String gate = fields[2];
817 String flags = fields[3]; // future use?
818 String mask = fields[7];
819 try {
820 // address stored as a hex string, ex: 0014A8C0
821 InetAddress destAddr =
822 NetworkUtils.intToInetAddress((int)Long.parseLong(dest, 16));
823 int prefixLength =
824 NetworkUtils.netmaskIntToPrefixLength(
825 (int)Long.parseLong(mask, 16));
826 LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
827
828 // address stored as a hex string, ex 0014A8C0
829 InetAddress gatewayAddr =
830 NetworkUtils.intToInetAddress((int)Long.parseLong(gate, 16));
831
Wink Saville7b5fd052013-03-15 05:07:04 +0000832 RouteInfo route = new RouteInfo(linkAddress, gatewayAddr);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700833 routes.add(route);
834 } catch (Exception e) {
835 Log.e(TAG, "Error parsing route " + s + " : " + e);
836 continue;
837 }
838 }
839 }
840 }
841
842 // v6 routes listed as:
843 // dest-addr prefixlength ?? ?? gateway-addr ?? ?? ?? ?? iface
844 for (String s : readRouteList("/proc/net/ipv6_route")) {
845 String[]fields = s.split("\\s+");
846 if (fields.length > 9) {
847 String iface = fields[9].trim();
848 if (interfaceName.equals(iface)) {
849 String dest = fields[0];
850 String prefix = fields[1];
851 String gate = fields[4];
852
853 try {
854 // prefix length stored as a hex string, ex 40
855 int prefixLength = Integer.parseInt(prefix, 16);
856
857 // address stored as a 32 char hex string
858 // ex fe800000000000000000000000000000
859 InetAddress destAddr = NetworkUtils.hexToInet6Address(dest);
860 LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
861
862 InetAddress gateAddr = NetworkUtils.hexToInet6Address(gate);
863
Wink Saville7b5fd052013-03-15 05:07:04 +0000864 RouteInfo route = new RouteInfo(linkAddress, gateAddr);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700865 routes.add(route);
866 } catch (Exception e) {
867 Log.e(TAG, "Error parsing route " + s + " : " + e);
868 continue;
869 }
870 }
871 }
872 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800873 return routes.toArray(new RouteInfo[routes.size()]);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700874 }
875
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800876 @Override
sy.yun9d9b74a2013-09-02 05:24:09 +0900877 public void setMtu(String iface, int mtu) {
878 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
879
880 final NativeDaemonEvent event;
881 try {
882 event = mConnector.execute("interface", "setmtu", iface, mtu);
883 } catch (NativeDaemonConnectorException e) {
884 throw e.rethrowAsParcelableException();
885 }
886 }
887
888 @Override
San Mehat873f2142010-01-14 10:25:07 -0800889 public void shutdown() {
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800890 // TODO: remove from aidl if nobody calls externally
891 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800892
Joe Onorato8a9b2202010-02-26 18:56:32 -0800893 Slog.d(TAG, "Shutting down");
San Mehat873f2142010-01-14 10:25:07 -0800894 }
895
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800896 @Override
San Mehat873f2142010-01-14 10:25:07 -0800897 public boolean getIpForwardingEnabled() throws IllegalStateException{
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800898 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800899
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800900 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700901 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800902 event = mConnector.execute("ipfwd", "status");
Kenny Roota80ce062010-06-01 13:23:53 -0700903 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800904 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700905 }
San Mehat873f2142010-01-14 10:25:07 -0800906
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800907 // 211 Forwarding enabled
908 event.checkCode(IpFwdStatusResult);
909 return event.getMessage().endsWith("enabled");
San Mehat873f2142010-01-14 10:25:07 -0800910 }
911
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800912 @Override
913 public void setIpForwardingEnabled(boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800914 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800915 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800916 mConnector.execute("ipfwd", enable ? "enable" : "disable");
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800917 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800918 throw e.rethrowAsParcelableException();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800919 }
San Mehat873f2142010-01-14 10:25:07 -0800920 }
921
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800922 @Override
923 public void startTethering(String[] dhcpRange) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800924 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700925 // cmd is "tether start first_start first_stop second_start second_stop ..."
926 // an odd number of addrs will fail
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800927
928 final Command cmd = new Command("tether", "start");
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700929 for (String d : dhcpRange) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800930 cmd.appendArg(d);
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700931 }
Kenny Roota80ce062010-06-01 13:23:53 -0700932
933 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800934 mConnector.execute(cmd);
Kenny Roota80ce062010-06-01 13:23:53 -0700935 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800936 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700937 }
San Mehat873f2142010-01-14 10:25:07 -0800938 }
939
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800940 @Override
941 public void stopTethering() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800942 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700943 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800944 mConnector.execute("tether", "stop");
Kenny Roota80ce062010-06-01 13:23:53 -0700945 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800946 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700947 }
San Mehat873f2142010-01-14 10:25:07 -0800948 }
949
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800950 @Override
951 public boolean isTetheringStarted() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800952 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800953
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800954 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700955 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800956 event = mConnector.execute("tether", "status");
Kenny Roota80ce062010-06-01 13:23:53 -0700957 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800958 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700959 }
San Mehat873f2142010-01-14 10:25:07 -0800960
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800961 // 210 Tethering services started
962 event.checkCode(TetherStatusResult);
963 return event.getMessage().endsWith("started");
San Mehat873f2142010-01-14 10:25:07 -0800964 }
Matthew Xiefe19f122012-07-12 16:03:32 -0700965
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800966 @Override
967 public void tetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800968 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700969 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800970 mConnector.execute("tether", "interface", "add", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700971 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800972 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700973 }
San Mehat873f2142010-01-14 10:25:07 -0800974 }
975
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800976 @Override
San Mehat873f2142010-01-14 10:25:07 -0800977 public void untetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800978 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700979 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800980 mConnector.execute("tether", "interface", "remove", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700981 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800982 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700983 }
San Mehat873f2142010-01-14 10:25:07 -0800984 }
985
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800986 @Override
987 public String[] listTetheredInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800988 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700989 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800990 return NativeDaemonEvent.filterMessageList(
991 mConnector.executeForList("tether", "interface", "list"),
992 TetherInterfaceListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700993 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800994 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700995 }
San Mehat873f2142010-01-14 10:25:07 -0800996 }
997
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800998 @Override
999 public void setDnsForwarders(String[] dns) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001000 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001001
1002 final Command cmd = new Command("tether", "dns", "set");
1003 for (String s : dns) {
1004 cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
1005 }
1006
San Mehat873f2142010-01-14 10:25:07 -08001007 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001008 mConnector.execute(cmd);
1009 } catch (NativeDaemonConnectorException e) {
1010 throw e.rethrowAsParcelableException();
San Mehat873f2142010-01-14 10:25:07 -08001011 }
1012 }
1013
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001014 @Override
1015 public String[] getDnsForwarders() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001016 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001017 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001018 return NativeDaemonEvent.filterMessageList(
1019 mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult);
Kenny Roota80ce062010-06-01 13:23:53 -07001020 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001021 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001022 }
San Mehat873f2142010-01-14 10:25:07 -08001023 }
1024
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001025 private void modifyNat(String action, String internalInterface, String externalInterface)
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001026 throws SocketException {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001027 final Command cmd = new Command("nat", action, internalInterface, externalInterface);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001028
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001029 final NetworkInterface internalNetworkInterface = NetworkInterface.getByName(
1030 internalInterface);
Robert Greenwalte83d1812011-11-21 14:44:39 -08001031 if (internalNetworkInterface == null) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001032 cmd.appendArg("0");
Robert Greenwalte83d1812011-11-21 14:44:39 -08001033 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001034 Collection<InterfaceAddress> interfaceAddresses = internalNetworkInterface
1035 .getInterfaceAddresses();
1036 cmd.appendArg(interfaceAddresses.size());
Robert Greenwalte83d1812011-11-21 14:44:39 -08001037 for (InterfaceAddress ia : interfaceAddresses) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001038 InetAddress addr = NetworkUtils.getNetworkPart(
1039 ia.getAddress(), ia.getNetworkPrefixLength());
1040 cmd.appendArg(addr.getHostAddress() + "/" + ia.getNetworkPrefixLength());
Robert Greenwalte83d1812011-11-21 14:44:39 -08001041 }
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001042 }
1043
Jeff Sharkey31c6e482011-11-18 17:09:01 -08001044 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001045 mConnector.execute(cmd);
Jeff Sharkey31c6e482011-11-18 17:09:01 -08001046 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001047 throw e.rethrowAsParcelableException();
Jeff Sharkey31c6e482011-11-18 17:09:01 -08001048 }
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001049 }
1050
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001051 @Override
1052 public void enableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001053 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001054 try {
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001055 modifyNat("enable", internalInterface, externalInterface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001056 } catch (SocketException e) {
1057 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001058 }
San Mehat873f2142010-01-14 10:25:07 -08001059 }
1060
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001061 @Override
1062 public void disableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001063 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001064 try {
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001065 modifyNat("disable", internalInterface, externalInterface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001066 } catch (SocketException e) {
1067 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001068 }
San Mehat873f2142010-01-14 10:25:07 -08001069 }
San Mehat72759df2010-01-19 13:50:37 -08001070
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001071 @Override
1072 public String[] listTtys() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001073 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001074 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001075 return NativeDaemonEvent.filterMessageList(
1076 mConnector.executeForList("list_ttys"), TtyListResult);
Kenny Roota80ce062010-06-01 13:23:53 -07001077 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001078 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001079 }
San Mehat72759df2010-01-19 13:50:37 -08001080 }
1081
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001082 @Override
1083 public void attachPppd(
1084 String tty, String localAddr, String remoteAddr, String dns1Addr, String dns2Addr) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001085 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat72759df2010-01-19 13:50:37 -08001086 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001087 mConnector.execute("pppd", "attach", tty,
Robert Greenwalte5903732011-02-22 16:00:42 -08001088 NetworkUtils.numericToInetAddress(localAddr).getHostAddress(),
1089 NetworkUtils.numericToInetAddress(remoteAddr).getHostAddress(),
1090 NetworkUtils.numericToInetAddress(dns1Addr).getHostAddress(),
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001091 NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress());
Kenny Roota80ce062010-06-01 13:23:53 -07001092 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001093 throw e.rethrowAsParcelableException();
San Mehat72759df2010-01-19 13:50:37 -08001094 }
1095 }
1096
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001097 @Override
1098 public void detachPppd(String tty) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001099 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001100 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001101 mConnector.execute("pppd", "detach", tty);
Kenny Roota80ce062010-06-01 13:23:53 -07001102 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001103 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001104 }
San Mehat72759df2010-01-19 13:50:37 -08001105 }
Robert Greenwaltce1200d2010-02-18 11:25:54 -08001106
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001107 @Override
1108 public void startAccessPoint(
Irfan Sheriff90542752012-06-19 15:44:35 -07001109 WifiConfiguration wifiConfig, String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001110 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001111 try {
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001112 wifiFirmwareReload(wlanIface, "AP");
Kenny Roota80ce062010-06-01 13:23:53 -07001113 if (wifiConfig == null) {
Irfan Sheriff90542752012-06-19 15:44:35 -07001114 mConnector.execute("softap", "set", wlanIface);
Kenny Roota80ce062010-06-01 13:23:53 -07001115 } else {
Irfan Sheriff90542752012-06-19 15:44:35 -07001116 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
Dmitry Shmidt28dd15b2013-06-10 14:37:08 -07001117 "broadcast", "6", getSecurityType(wifiConfig),
Kenny Root36062542013-06-10 11:09:28 -07001118 new SensitiveArg(wifiConfig.preSharedKey));
Kenny Roota80ce062010-06-01 13:23:53 -07001119 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001120 mConnector.execute("softap", "startap");
Kenny Roota80ce062010-06-01 13:23:53 -07001121 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001122 throw e.rethrowAsParcelableException();
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -08001123 }
Irfan Sheriff5321aef2010-02-12 12:35:59 -08001124 }
1125
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001126 private static String getSecurityType(WifiConfiguration wifiConfig) {
Irfan Sheriffec8d23a2011-02-16 17:00:33 -08001127 switch (wifiConfig.getAuthType()) {
1128 case KeyMgmt.WPA_PSK:
1129 return "wpa-psk";
1130 case KeyMgmt.WPA2_PSK:
1131 return "wpa2-psk";
1132 default:
1133 return "open";
1134 }
1135 }
1136
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001137 /* @param mode can be "AP", "STA" or "P2P" */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001138 @Override
1139 public void wifiFirmwareReload(String wlanIface, String mode) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001140 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001141 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001142 mConnector.execute("softap", "fwreload", wlanIface, mode);
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001143 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001144 throw e.rethrowAsParcelableException();
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001145 }
1146 }
1147
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001148 @Override
1149 public void stopAccessPoint(String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001150 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001151 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001152 mConnector.execute("softap", "stopap");
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001153 wifiFirmwareReload(wlanIface, "STA");
Kenny Roota80ce062010-06-01 13:23:53 -07001154 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001155 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001156 }
Irfan Sheriff5321aef2010-02-12 12:35:59 -08001157 }
1158
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001159 @Override
Irfan Sheriff90542752012-06-19 15:44:35 -07001160 public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001161 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001162 try {
1163 if (wifiConfig == null) {
Irfan Sheriff90542752012-06-19 15:44:35 -07001164 mConnector.execute("softap", "set", wlanIface);
Kenny Roota80ce062010-06-01 13:23:53 -07001165 } else {
Irfan Sheriff90542752012-06-19 15:44:35 -07001166 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
Dmitry Shmidt28dd15b2013-06-10 14:37:08 -07001167 "broadcast", "6", getSecurityType(wifiConfig),
Kenny Root36062542013-06-10 11:09:28 -07001168 new SensitiveArg(wifiConfig.preSharedKey));
Kenny Roota80ce062010-06-01 13:23:53 -07001169 }
1170 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001171 throw e.rethrowAsParcelableException();
Irfan Sheriffc2f54c22010-03-18 14:02:22 -07001172 }
1173 }
San Mehat91cac642010-03-31 14:31:36 -07001174
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001175 @Override
Haoyu Bai04124232012-06-28 15:26:19 -07001176 public void addIdleTimer(String iface, int timeout, String label) {
1177 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1178
1179 if (DBG) Slog.d(TAG, "Adding idletimer");
1180
1181 synchronized (mIdleTimerLock) {
1182 IdleTimerParams params = mActiveIdleTimers.get(iface);
1183 if (params != null) {
1184 // the interface already has idletimer, update network count
1185 params.networkCount++;
1186 return;
1187 }
1188
1189 try {
1190 mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
1191 } catch (NativeDaemonConnectorException e) {
1192 throw e.rethrowAsParcelableException();
1193 }
1194 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
1195 }
1196 }
1197
1198 @Override
1199 public void removeIdleTimer(String iface) {
1200 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1201
1202 if (DBG) Slog.d(TAG, "Removing idletimer");
1203
1204 synchronized (mIdleTimerLock) {
1205 IdleTimerParams params = mActiveIdleTimers.get(iface);
1206 if (params == null || --(params.networkCount) > 0) {
1207 return;
1208 }
1209
1210 try {
1211 mConnector.execute("idletimer", "remove", iface,
1212 Integer.toString(params.timeout), params.label);
1213 } catch (NativeDaemonConnectorException e) {
1214 throw e.rethrowAsParcelableException();
1215 }
1216 mActiveIdleTimers.remove(iface);
1217 }
1218 }
1219
1220 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001221 public NetworkStats getNetworkStatsSummaryDev() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001222 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001223 try {
1224 return mStatsFactory.readNetworkStatsSummaryDev();
1225 } catch (IOException e) {
1226 throw new IllegalStateException(e);
1227 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001228 }
1229
1230 @Override
1231 public NetworkStats getNetworkStatsSummaryXt() {
1232 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001233 try {
1234 return mStatsFactory.readNetworkStatsSummaryXt();
1235 } catch (IOException e) {
1236 throw new IllegalStateException(e);
1237 }
Jeff Sharkeyae2c1812011-10-04 13:11:40 -07001238 }
1239
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001240 @Override
Jeff Sharkey9a13f362011-04-26 16:25:36 -07001241 public NetworkStats getNetworkStatsDetail() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001242 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001243 try {
1244 return mStatsFactory.readNetworkStatsDetail(UID_ALL);
1245 } catch (IOException e) {
1246 throw new IllegalStateException(e);
1247 }
San Mehat91cac642010-03-31 14:31:36 -07001248 }
1249
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001250 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001251 public void setInterfaceQuota(String iface, long quotaBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001252 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001253
Jeff Sharkey350083e2011-06-29 10:45:16 -07001254 // silently discard when control disabled
1255 // TODO: eventually migrate to be always enabled
1256 if (!mBandwidthControlEnabled) return;
1257
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001258 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001259 if (mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001260 throw new IllegalStateException("iface " + iface + " already has quota");
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001261 }
1262
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001263 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001264 // TODO: support quota shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001265 mConnector.execute("bandwidth", "setiquota", iface, quotaBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001266 mActiveQuotas.put(iface, quotaBytes);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001267 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001268 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001269 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001270 }
1271 }
1272
1273 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001274 public void removeInterfaceQuota(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001275 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001276
Jeff Sharkey350083e2011-06-29 10:45:16 -07001277 // silently discard when control disabled
1278 // TODO: eventually migrate to be always enabled
1279 if (!mBandwidthControlEnabled) return;
1280
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001281 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001282 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001283 // TODO: eventually consider throwing
1284 return;
1285 }
1286
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001287 mActiveQuotas.remove(iface);
1288 mActiveAlerts.remove(iface);
Jeff Sharkey38ddeaa2011-11-08 13:04:22 -08001289
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001290 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001291 // TODO: support quota shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001292 mConnector.execute("bandwidth", "removeiquota", iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001293 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001294 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001295 }
1296 }
1297 }
1298
1299 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001300 public void setInterfaceAlert(String iface, long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001301 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001302
1303 // silently discard when control disabled
1304 // TODO: eventually migrate to be always enabled
1305 if (!mBandwidthControlEnabled) return;
1306
1307 // quick sanity check
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001308 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001309 throw new IllegalStateException("setting alert requires existing quota on iface");
1310 }
1311
1312 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001313 if (mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001314 throw new IllegalStateException("iface " + iface + " already has alert");
1315 }
1316
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001317 try {
1318 // TODO: support alert shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001319 mConnector.execute("bandwidth", "setinterfacealert", iface, alertBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001320 mActiveAlerts.put(iface, alertBytes);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001321 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001322 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001323 }
1324 }
1325 }
1326
1327 @Override
1328 public void removeInterfaceAlert(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001329 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001330
1331 // silently discard when control disabled
1332 // TODO: eventually migrate to be always enabled
1333 if (!mBandwidthControlEnabled) return;
1334
1335 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001336 if (!mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001337 // TODO: eventually consider throwing
1338 return;
1339 }
1340
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001341 try {
1342 // TODO: support alert shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001343 mConnector.execute("bandwidth", "removeinterfacealert", iface);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001344 mActiveAlerts.remove(iface);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001345 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001346 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001347 }
1348 }
1349 }
1350
1351 @Override
1352 public void setGlobalAlert(long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001353 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001354
1355 // silently discard when control disabled
1356 // TODO: eventually migrate to be always enabled
1357 if (!mBandwidthControlEnabled) return;
1358
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001359 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001360 mConnector.execute("bandwidth", "setglobalalert", alertBytes);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001361 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001362 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001363 }
1364 }
1365
1366 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001367 public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001368 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001369
Jeff Sharkey350083e2011-06-29 10:45:16 -07001370 // silently discard when control disabled
1371 // TODO: eventually migrate to be always enabled
1372 if (!mBandwidthControlEnabled) return;
1373
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001374 synchronized (mQuotaLock) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001375 final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
1376 if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
1377 // TODO: eventually consider throwing
1378 return;
1379 }
1380
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001381 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001382 mConnector.execute("bandwidth",
1383 rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001384 if (rejectOnQuotaInterfaces) {
1385 mUidRejectOnQuota.put(uid, true);
1386 } else {
1387 mUidRejectOnQuota.delete(uid);
1388 }
1389 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001390 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001391 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001392 }
1393 }
1394
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001395 @Override
1396 public boolean isBandwidthControlEnabled() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001397 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001398 return mBandwidthControlEnabled;
1399 }
1400
1401 @Override
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001402 public NetworkStats getNetworkStatsUidDetail(int uid) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001403 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001404 try {
1405 return mStatsFactory.readNetworkStatsDetail(uid);
1406 } catch (IOException e) {
1407 throw new IllegalStateException(e);
1408 }
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001409 }
1410
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001411 @Override
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001412 public NetworkStats getNetworkStatsTethering() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001413 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001414
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001415 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001416 try {
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001417 final NativeDaemonEvent[] events = mConnector.executeForList(
1418 "bandwidth", "gettetherstats");
1419 for (NativeDaemonEvent event : events) {
1420 if (event.getCode() != TetheringStatsListResult) continue;
1421
1422 // 114 ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
1423 final StringTokenizer tok = new StringTokenizer(event.getMessage());
1424 try {
1425 final String ifaceIn = tok.nextToken();
1426 final String ifaceOut = tok.nextToken();
1427
1428 final NetworkStats.Entry entry = new NetworkStats.Entry();
1429 entry.iface = ifaceOut;
1430 entry.uid = UID_TETHERING;
1431 entry.set = SET_DEFAULT;
1432 entry.tag = TAG_NONE;
1433 entry.rxBytes = Long.parseLong(tok.nextToken());
1434 entry.rxPackets = Long.parseLong(tok.nextToken());
1435 entry.txBytes = Long.parseLong(tok.nextToken());
1436 entry.txPackets = Long.parseLong(tok.nextToken());
1437 stats.combineValues(entry);
1438 } catch (NoSuchElementException e) {
1439 throw new IllegalStateException("problem parsing tethering stats: " + event);
1440 } catch (NumberFormatException e) {
1441 throw new IllegalStateException("problem parsing tethering stats: " + event);
1442 }
1443 }
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001444 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001445 throw e.rethrowAsParcelableException();
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001446 }
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001447 return stats;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001448 }
1449
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001450 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001451 public void setDefaultInterfaceForDns(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001452 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001453 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001454 mConnector.execute("resolver", "setdefaultif", iface);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001455 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001456 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001457 }
1458 }
1459
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001460 @Override
Robert Greenwalt8058f622012-11-09 10:52:27 -08001461 public void setDnsServersForInterface(String iface, String[] servers, String domains) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001462 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001463
Robert Greenwalt8058f622012-11-09 10:52:27 -08001464 final Command cmd = new Command("resolver", "setifdns", iface,
1465 (domains == null ? "" : domains));
1466
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001467 for (String s : servers) {
1468 InetAddress a = NetworkUtils.numericToInetAddress(s);
1469 if (a.isAnyLocalAddress() == false) {
1470 cmd.appendArg(a.getHostAddress());
Mattias Falk7475c0c2011-04-04 16:10:36 +02001471 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001472 }
1473
1474 try {
1475 mConnector.execute(cmd);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001476 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001477 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001478 }
1479 }
1480
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001481 @Override
Chad Brubaker3277620a2013-06-12 13:37:30 -07001482 public void setUidRangeRoute(String iface, int uid_start, int uid_end) {
1483 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1484 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001485 mConnector.execute("interface", "fwmark",
Chad Brubaker3277620a2013-06-12 13:37:30 -07001486 "uid", "add", iface, uid_start, uid_end);
1487 } catch (NativeDaemonConnectorException e) {
1488 throw e.rethrowAsParcelableException();
1489 }
1490 }
1491
1492 @Override
1493 public void clearUidRangeRoute(String iface, int uid_start, int uid_end) {
1494 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1495 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001496 mConnector.execute("interface", "fwmark",
Chad Brubaker3277620a2013-06-12 13:37:30 -07001497 "uid", "remove", iface, uid_start, uid_end);
1498 } catch (NativeDaemonConnectorException e) {
1499 throw e.rethrowAsParcelableException();
1500 }
1501 }
1502
1503 @Override
1504 public void setMarkedForwarding(String iface) {
1505 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1506 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001507 mConnector.execute("interface", "fwmark", "rule", "add", iface);
Chad Brubaker3277620a2013-06-12 13:37:30 -07001508 } catch (NativeDaemonConnectorException e) {
1509 throw e.rethrowAsParcelableException();
1510 }
1511 }
1512
1513 @Override
1514 public void clearMarkedForwarding(String iface) {
1515 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1516 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001517 mConnector.execute("interface", "fwmark", "rule", "remove", iface);
1518 } catch (NativeDaemonConnectorException e) {
1519 throw e.rethrowAsParcelableException();
1520 }
1521 }
1522
1523 @Override
1524 public int getMarkForUid(int uid) {
1525 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1526 final NativeDaemonEvent event;
1527 try {
1528 event = mConnector.execute("interface", "fwmark", "get", "mark", uid);
1529 } catch (NativeDaemonConnectorException e) {
1530 throw e.rethrowAsParcelableException();
1531 }
1532 event.checkCode(GetMarkResult);
1533 return Integer.parseInt(event.getMessage());
1534 }
1535
1536 @Override
1537 public int getMarkForProtect() {
1538 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1539 final NativeDaemonEvent event;
1540 try {
1541 event = mConnector.execute("interface", "fwmark", "get", "protect");
1542 } catch (NativeDaemonConnectorException e) {
1543 throw e.rethrowAsParcelableException();
1544 }
1545 event.checkCode(GetMarkResult);
1546 return Integer.parseInt(event.getMessage());
1547 }
1548
1549 @Override
1550 public void setMarkedForwardingRoute(String iface, RouteInfo route) {
1551 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1552 try {
1553 LinkAddress dest = route.getDestination();
1554 mConnector.execute("interface", "fwmark", "route", "add", iface,
1555 dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
1556 } catch (NativeDaemonConnectorException e) {
1557 throw e.rethrowAsParcelableException();
1558 }
1559 }
1560
1561 @Override
1562 public void clearMarkedForwardingRoute(String iface, RouteInfo route) {
1563 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1564 try {
1565 LinkAddress dest = route.getDestination();
1566 mConnector.execute("interface", "fwmark", "route", "remove", iface,
1567 dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
Chad Brubaker3277620a2013-06-12 13:37:30 -07001568 } catch (NativeDaemonConnectorException e) {
1569 throw e.rethrowAsParcelableException();
1570 }
1571 }
1572
1573 @Override
Chad Brubakerf336d722013-07-15 16:34:04 -07001574 public void setHostExemption(LinkAddress host) {
1575 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1576 try {
1577 mConnector.execute("interface", "fwmark", "exempt", "add", host);
1578 } catch (NativeDaemonConnectorException e) {
1579 throw e.rethrowAsParcelableException();
1580 }
1581 }
1582
1583 @Override
1584 public void clearHostExemption(LinkAddress host) {
1585 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1586 try {
1587 mConnector.execute("interface", "fwmark", "exempt", "remove", host);
1588 } catch (NativeDaemonConnectorException e) {
1589 throw e.rethrowAsParcelableException();
1590 }
1591 }
1592
1593 @Override
Chad Brubaker3277620a2013-06-12 13:37:30 -07001594 public void setDnsInterfaceForUidRange(String iface, int uid_start, int uid_end) {
1595 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1596 try {
1597 mConnector.execute("resolver", "setifaceforuidrange", iface, uid_start, uid_end);
1598 } catch (NativeDaemonConnectorException e) {
1599 throw e.rethrowAsParcelableException();
1600 }
1601 }
1602
1603 @Override
1604 public void clearDnsInterfaceForUidRange(int uid_start, int uid_end) {
1605 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1606 try {
1607 mConnector.execute("resolver", "clearifaceforuidrange", uid_start, uid_end);
1608 } catch (NativeDaemonConnectorException e) {
1609 throw e.rethrowAsParcelableException();
1610 }
1611 }
1612
1613 @Override
1614 public void clearDnsInterfaceMaps() {
1615 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1616 try {
1617 mConnector.execute("resolver", "clearifacemapping");
1618 } catch (NativeDaemonConnectorException e) {
1619 throw e.rethrowAsParcelableException();
1620 }
1621 }
1622
1623
1624 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001625 public void flushDefaultDnsCache() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001626 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001627 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001628 mConnector.execute("resolver", "flushdefaultif");
Mattias Falk7475c0c2011-04-04 16:10:36 +02001629 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001630 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001631 }
1632 }
1633
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001634 @Override
1635 public void flushInterfaceDnsCache(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001636 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001637 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001638 mConnector.execute("resolver", "flushif", iface);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001639 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001640 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001641 }
1642 }
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -07001643
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001644 @Override
1645 public void setFirewallEnabled(boolean enabled) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001646 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001647 try {
1648 mConnector.execute("firewall", enabled ? "enable" : "disable");
1649 mFirewallEnabled = enabled;
1650 } catch (NativeDaemonConnectorException e) {
1651 throw e.rethrowAsParcelableException();
1652 }
1653 }
1654
1655 @Override
1656 public boolean isFirewallEnabled() {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001657 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001658 return mFirewallEnabled;
1659 }
1660
1661 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001662 public void setFirewallInterfaceRule(String iface, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001663 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001664 Preconditions.checkState(mFirewallEnabled);
1665 final String rule = allow ? ALLOW : DENY;
1666 try {
1667 mConnector.execute("firewall", "set_interface_rule", iface, rule);
1668 } catch (NativeDaemonConnectorException e) {
1669 throw e.rethrowAsParcelableException();
1670 }
1671 }
1672
1673 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001674 public void setFirewallEgressSourceRule(String addr, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001675 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001676 Preconditions.checkState(mFirewallEnabled);
1677 final String rule = allow ? ALLOW : DENY;
1678 try {
1679 mConnector.execute("firewall", "set_egress_source_rule", addr, rule);
1680 } catch (NativeDaemonConnectorException e) {
1681 throw e.rethrowAsParcelableException();
1682 }
1683 }
1684
1685 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001686 public void setFirewallEgressDestRule(String addr, int port, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001687 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001688 Preconditions.checkState(mFirewallEnabled);
1689 final String rule = allow ? ALLOW : DENY;
1690 try {
1691 mConnector.execute("firewall", "set_egress_dest_rule", addr, port, rule);
1692 } catch (NativeDaemonConnectorException e) {
1693 throw e.rethrowAsParcelableException();
1694 }
1695 }
1696
1697 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001698 public void setFirewallUidRule(int uid, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001699 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001700 Preconditions.checkState(mFirewallEnabled);
1701 final String rule = allow ? ALLOW : DENY;
1702 try {
1703 mConnector.execute("firewall", "set_uid_rule", uid, rule);
1704 } catch (NativeDaemonConnectorException e) {
1705 throw e.rethrowAsParcelableException();
1706 }
1707 }
1708
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001709 private static void enforceSystemUid() {
1710 final int uid = Binder.getCallingUid();
1711 if (uid != Process.SYSTEM_UID) {
1712 throw new SecurityException("Only available to AID_SYSTEM");
1713 }
1714 }
1715
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001716 @Override
Mattias Falk8b47b362011-08-23 14:15:13 +02001717 public void setDnsInterfaceForPid(String iface, int pid) throws IllegalStateException {
1718 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1719 try {
Jeff Sharkey0c232f52013-02-13 11:27:24 -08001720 mConnector.execute("resolver", "setifaceforpid", iface, pid);
Mattias Falk8b47b362011-08-23 14:15:13 +02001721 } catch (NativeDaemonConnectorException e) {
1722 throw new IllegalStateException(
1723 "Error communicating with native deamon to set interface for pid" + iface, e);
1724 }
1725 }
1726
1727 @Override
1728 public void clearDnsInterfaceForPid(int pid) throws IllegalStateException {
1729 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1730 try {
Jeff Sharkey0c232f52013-02-13 11:27:24 -08001731 mConnector.execute("resolver", "clearifaceforpid", pid);
Mattias Falk8b47b362011-08-23 14:15:13 +02001732 } catch (NativeDaemonConnectorException e) {
1733 throw new IllegalStateException(
1734 "Error communicating with native deamon to clear interface for pid " + pid, e);
1735 }
1736 }
1737
Lorenzo Colitti79751842013-02-28 16:16:03 +09001738 @Override
1739 public void startClatd(String interfaceName) throws IllegalStateException {
1740 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1741
1742 try {
1743 mConnector.execute("clatd", "start", interfaceName);
1744 } catch (NativeDaemonConnectorException e) {
1745 throw e.rethrowAsParcelableException();
1746 }
1747 }
1748
1749 @Override
1750 public void stopClatd() throws IllegalStateException {
1751 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1752
1753 try {
1754 mConnector.execute("clatd", "stop");
1755 } catch (NativeDaemonConnectorException e) {
1756 throw e.rethrowAsParcelableException();
1757 }
1758 }
1759
1760 @Override
1761 public boolean isClatdStarted() {
1762 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1763
1764 final NativeDaemonEvent event;
1765 try {
1766 event = mConnector.execute("clatd", "status");
1767 } catch (NativeDaemonConnectorException e) {
1768 throw e.rethrowAsParcelableException();
1769 }
1770
1771 event.checkCode(ClatdStatusResult);
1772 return event.getMessage().endsWith("started");
1773 }
1774
Mattias Falk8b47b362011-08-23 14:15:13 +02001775 /** {@inheritDoc} */
Jeff Sharkey7b4596f2013-02-25 10:55:29 -08001776 @Override
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -07001777 public void monitor() {
1778 if (mConnector != null) {
1779 mConnector.monitor();
1780 }
1781 }
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001782
1783 @Override
1784 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1785 mContext.enforceCallingOrSelfPermission(DUMP, TAG);
1786
Robert Greenwalt470fd722012-01-18 12:51:15 -08001787 pw.println("NetworkManagementService NativeDaemonConnector Log:");
1788 mConnector.dump(fd, pw, args);
1789 pw.println();
1790
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001791 pw.print("Bandwidth control enabled: "); pw.println(mBandwidthControlEnabled);
1792
1793 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001794 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
1795 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001796 }
1797
1798 synchronized (mUidRejectOnQuota) {
1799 pw.print("UID reject on quota ifaces: [");
1800 final int size = mUidRejectOnQuota.size();
1801 for (int i = 0; i < size; i++) {
1802 pw.print(mUidRejectOnQuota.keyAt(i));
1803 if (i < size - 1) pw.print(",");
1804 }
1805 pw.println("]");
1806 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001807
1808 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001809 }
San Mehat873f2142010-01-14 10:25:07 -08001810}