blob: 16cfa666901ccf24a2df7a08606944f19eb749f1 [file] [log] [blame]
San Mehat873f2142010-01-14 10:25:07 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
Jeff Sharkey4529bb62011-12-14 10:31:54 -080019import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070020import static android.Manifest.permission.DUMP;
Jeff Sharkeyaf75c332011-11-18 12:41:12 -080021import static android.Manifest.permission.SHUTDOWN;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070022import static android.net.NetworkStats.SET_DEFAULT;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070023import static android.net.NetworkStats.TAG_NONE;
24import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyae2c1812011-10-04 13:11:40 -070025import static android.net.TrafficStats.UID_TETHERING;
Lorenzo Colitti79751842013-02-28 16:16:03 +090026import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080027import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
28import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080029import static com.android.server.NetworkManagementService.NetdResponseCode.IpFwdStatusResult;
30import static com.android.server.NetworkManagementService.NetdResponseCode.TetherDnsFwdTgtListResult;
31import static com.android.server.NetworkManagementService.NetdResponseCode.TetherInterfaceListResult;
32import static com.android.server.NetworkManagementService.NetdResponseCode.TetherStatusResult;
33import static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsResult;
34import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
Chad Brubakercca54c42013-06-27 17:41:38 -070035import static com.android.server.NetworkManagementService.NetdResponseCode.GetMarkResult;
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";
98
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080099 private static final String ADD = "add";
100 private static final String REMOVE = "remove";
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700101
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700102 private static final String ALLOW = "allow";
103 private static final String DENY = "deny";
104
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700105 private static final String DEFAULT = "default";
106 private static final String SECONDARY = "secondary";
107
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700108 /**
109 * Name representing {@link #setGlobalAlert(long)} limit when delivered to
110 * {@link INetworkManagementEventObserver#limitReached(String, String)}.
111 */
112 public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
113
San Mehat873f2142010-01-14 10:25:07 -0800114 class NetdResponseCode {
JP Abgrall12b933d2011-07-14 18:09:22 -0700115 /* Keep in sync with system/netd/ResponseCode.h */
San Mehat873f2142010-01-14 10:25:07 -0800116 public static final int InterfaceListResult = 110;
117 public static final int TetherInterfaceListResult = 111;
118 public static final int TetherDnsFwdTgtListResult = 112;
San Mehat72759df2010-01-19 13:50:37 -0800119 public static final int TtyListResult = 113;
San Mehat873f2142010-01-14 10:25:07 -0800120
121 public static final int TetherStatusResult = 210;
122 public static final int IpFwdStatusResult = 211;
San Mehated4fc8a2010-01-22 12:28:36 -0800123 public static final int InterfaceGetCfgResult = 213;
Robert Greenwalte3253922010-02-18 09:23:25 -0800124 public static final int SoftapStatusResult = 214;
San Mehat91cac642010-03-31 14:31:36 -0700125 public static final int InterfaceRxCounterResult = 216;
126 public static final int InterfaceTxCounterResult = 217;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700127 public static final int QuotaCounterResult = 220;
128 public static final int TetheringStatsResult = 221;
Selim Gurun84c00c62012-02-27 15:42:38 -0800129 public static final int DnsProxyQueryResult = 222;
Lorenzo Colitti79751842013-02-28 16:16:03 +0900130 public static final int ClatdStatusResult = 223;
Chad Brubakercca54c42013-06-27 17:41:38 -0700131 public static final int GetMarkResult = 225;
Robert Greenwalte3253922010-02-18 09:23:25 -0800132
133 public static final int InterfaceChange = 600;
JP Abgrall12b933d2011-07-14 18:09:22 -0700134 public static final int BandwidthControl = 601;
Haoyu Bai6b7358d2012-07-17 16:36:50 -0700135 public static final int InterfaceClassActivity = 613;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900136 public static final int InterfaceAddressChange = 614;
San Mehat873f2142010-01-14 10:25:07 -0800137 }
138
139 /**
140 * Binder context for this service
141 */
142 private Context mContext;
143
144 /**
145 * connector object for communicating with netd
146 */
147 private NativeDaemonConnector mConnector;
148
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700149 private final Handler mMainHandler = new Handler();
150
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700151 private Thread mThread;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700152 private CountDownLatch mConnectedSignal = new CountDownLatch(1);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700153
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800154 private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
155 new RemoteCallbackList<INetworkManagementEventObserver>();
San Mehat4d02d002010-01-22 16:07:46 -0800156
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700157 private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
158
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700159 private Object mQuotaLock = new Object();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700160 /** Set of interfaces with active quotas. */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700161 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700162 /** Set of interfaces with active alerts. */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700163 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700164 /** Set of UIDs with active reject rules. */
165 private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
166
Haoyu Bai04124232012-06-28 15:26:19 -0700167 private Object mIdleTimerLock = new Object();
168 /** Set of interfaces with active idle timers. */
169 private static class IdleTimerParams {
170 public final int timeout;
171 public final String label;
172 public int networkCount;
173
174 IdleTimerParams(int timeout, String label) {
175 this.timeout = timeout;
176 this.label = label;
177 this.networkCount = 1;
178 }
179 }
180 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
181
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700182 private volatile boolean mBandwidthControlEnabled;
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700183 private volatile boolean mFirewallEnabled;
Jeff Sharkey350083e2011-06-29 10:45:16 -0700184
San Mehat873f2142010-01-14 10:25:07 -0800185 /**
186 * Constructs a new NetworkManagementService instance
187 *
188 * @param context Binder context for this service
189 */
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700190 private NetworkManagementService(Context context) {
San Mehat873f2142010-01-14 10:25:07 -0800191 mContext = context;
San Mehat4d02d002010-01-22 16:07:46 -0800192
Marco Nelissen62dbb222010-02-18 10:56:30 -0800193 if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
194 return;
195 }
196
San Mehat873f2142010-01-14 10:25:07 -0800197 mConnector = new NativeDaemonConnector(
Robert Greenwalt5a0c3202012-05-22 16:07:46 -0700198 new NetdCallbackReceiver(), "netd", 10, NETD_TAG, 160);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700199 mThread = new Thread(mConnector, NETD_TAG);
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700200
201 // Add ourself to the Watchdog monitors.
202 Watchdog.getInstance().addMonitor(this);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700203 }
204
205 public static NetworkManagementService create(Context context) throws InterruptedException {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700206 final NetworkManagementService service = new NetworkManagementService(context);
207 final CountDownLatch connectedSignal = service.mConnectedSignal;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700208 if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
209 service.mThread.start();
210 if (DBG) Slog.d(TAG, "Awaiting socket connection");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700211 connectedSignal.await();
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700212 if (DBG) Slog.d(TAG, "Connected");
213 return service;
San Mehat873f2142010-01-14 10:25:07 -0800214 }
215
Jeff Sharkey350083e2011-06-29 10:45:16 -0700216 public void systemReady() {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700217 prepareNativeDaemon();
218 if (DBG) Slog.d(TAG, "Prepared");
Jeff Sharkey350083e2011-06-29 10:45:16 -0700219 }
220
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800221 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800222 public void registerObserver(INetworkManagementEventObserver observer) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800223 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800224 mObservers.register(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800225 }
226
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800227 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800228 public void unregisterObserver(INetworkManagementEventObserver observer) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800229 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800230 mObservers.unregister(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800231 }
232
233 /**
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700234 * Notify our observers of an interface status change
San Mehat4d02d002010-01-22 16:07:46 -0800235 */
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700236 private void notifyInterfaceStatusChanged(String iface, boolean up) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800237 final int length = mObservers.beginBroadcast();
238 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800239 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800240 mObservers.getBroadcastItem(i).interfaceStatusChanged(iface, up);
241 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900242 } catch (RuntimeException e) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700243 }
244 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800245 mObservers.finishBroadcast();
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700246 }
247
248 /**
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700249 * Notify our observers of an interface link state change
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700250 * (typically, an Ethernet cable has been plugged-in or unplugged).
251 */
252 private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800253 final int length = mObservers.beginBroadcast();
254 for (int i = 0; i < length; i++) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700255 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800256 mObservers.getBroadcastItem(i).interfaceLinkStateChanged(iface, up);
257 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900258 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800259 }
260 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800261 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800262 }
263
264 /**
265 * Notify our observers of an interface addition.
266 */
267 private void notifyInterfaceAdded(String iface) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800268 final int length = mObservers.beginBroadcast();
269 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800270 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800271 mObservers.getBroadcastItem(i).interfaceAdded(iface);
272 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900273 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800274 }
275 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800276 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800277 }
278
279 /**
280 * Notify our observers of an interface removal.
281 */
282 private void notifyInterfaceRemoved(String iface) {
Jeff Sharkey89b8a212011-10-11 11:58:11 -0700283 // netd already clears out quota and alerts for removed ifaces; update
284 // our sanity-checking state.
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700285 mActiveAlerts.remove(iface);
286 mActiveQuotas.remove(iface);
Jeff Sharkey89b8a212011-10-11 11:58:11 -0700287
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800288 final int length = mObservers.beginBroadcast();
289 for (int i = 0; i < length; i++) {
San Mehat4d02d002010-01-22 16:07:46 -0800290 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800291 mObservers.getBroadcastItem(i).interfaceRemoved(iface);
292 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900293 } catch (RuntimeException e) {
San Mehat4d02d002010-01-22 16:07:46 -0800294 }
295 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800296 mObservers.finishBroadcast();
San Mehat4d02d002010-01-22 16:07:46 -0800297 }
298
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700299 /**
JP Abgrall12b933d2011-07-14 18:09:22 -0700300 * Notify our observers of a limit reached.
301 */
302 private void notifyLimitReached(String limitName, String iface) {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800303 final int length = mObservers.beginBroadcast();
304 for (int i = 0; i < length; i++) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700305 try {
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800306 mObservers.getBroadcastItem(i).limitReached(limitName, iface);
307 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900308 } catch (RuntimeException e) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700309 }
310 }
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800311 mObservers.finishBroadcast();
JP Abgrall12b933d2011-07-14 18:09:22 -0700312 }
313
314 /**
Haoyu Baidb3c8672012-06-20 14:29:57 -0700315 * Notify our observers of a change in the data activity state of the interface
316 */
317 private void notifyInterfaceClassActivity(String label, boolean active) {
318 final int length = mObservers.beginBroadcast();
319 for (int i = 0; i < length; i++) {
320 try {
321 mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(label, active);
322 } catch (RemoteException e) {
Lorenzo Colittid9b3d552013-03-17 03:21:35 +0900323 } catch (RuntimeException e) {
Haoyu Baidb3c8672012-06-20 14:29:57 -0700324 }
325 }
326 mObservers.finishBroadcast();
327 }
328
329 /**
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700330 * Prepare native daemon once connected, enabling modules and pushing any
331 * existing in-memory rules.
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700332 */
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700333 private void prepareNativeDaemon() {
334 mBandwidthControlEnabled = false;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700335
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700336 // only enable bandwidth control when support exists
337 final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists();
338 if (hasKernelSupport) {
339 Slog.d(TAG, "enabling bandwidth control");
340 try {
341 mConnector.execute("bandwidth", "enable");
342 mBandwidthControlEnabled = true;
343 } catch (NativeDaemonConnectorException e) {
344 Log.wtf(TAG, "problem enabling bandwidth controls", e);
345 }
346 } else {
347 Slog.d(TAG, "not enabling bandwidth control");
348 }
349
350 SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0");
351
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700352 if (mBandwidthControlEnabled) {
353 try {
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700354 IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME))
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700355 .noteNetworkStatsEnabled();
356 } catch (RemoteException e) {
357 }
358 }
359
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700360 // push any existing quota or UID rules
361 synchronized (mQuotaLock) {
362 int size = mActiveQuotas.size();
363 if (size > 0) {
364 Slog.d(TAG, "pushing " + size + " active quota rules");
365 final HashMap<String, Long> activeQuotas = mActiveQuotas;
366 mActiveQuotas = Maps.newHashMap();
367 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
368 setInterfaceQuota(entry.getKey(), entry.getValue());
369 }
370 }
371
372 size = mActiveAlerts.size();
373 if (size > 0) {
374 Slog.d(TAG, "pushing " + size + " active alert rules");
375 final HashMap<String, Long> activeAlerts = mActiveAlerts;
376 mActiveAlerts = Maps.newHashMap();
377 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
378 setInterfaceAlert(entry.getKey(), entry.getValue());
379 }
380 }
381
382 size = mUidRejectOnQuota.size();
383 if (size > 0) {
384 Slog.d(TAG, "pushing " + size + " active uid rules");
385 final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota;
386 mUidRejectOnQuota = new SparseBooleanArray();
387 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
388 setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i));
389 }
390 }
391 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700392
393 // TODO: Push any existing firewall state
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700394 setFirewallEnabled(mFirewallEnabled || LockdownVpnTracker.isEnabled());
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700395 }
San Mehat4d02d002010-01-22 16:07:46 -0800396
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900397 /**
398 * Notify our observers of a new or updated interface address.
399 */
400 private void notifyAddressUpdated(String address, String iface, int flags, int scope) {
401 final int length = mObservers.beginBroadcast();
402 for (int i = 0; i < length; i++) {
403 try {
404 mObservers.getBroadcastItem(i).addressUpdated(address, iface, flags, scope);
405 } catch (RemoteException e) {
406 } catch (RuntimeException e) {
407 }
408 }
409 mObservers.finishBroadcast();
410 }
411
412 /**
413 * Notify our observers of a deleted interface address.
414 */
415 private void notifyAddressRemoved(String address, String iface, int flags, int scope) {
416 final int length = mObservers.beginBroadcast();
417 for (int i = 0; i < length; i++) {
418 try {
419 mObservers.getBroadcastItem(i).addressRemoved(address, iface, flags, scope);
420 } catch (RemoteException e) {
421 } catch (RuntimeException e) {
422 }
423 }
424 mObservers.finishBroadcast();
425 }
426
San Mehat873f2142010-01-14 10:25:07 -0800427 //
428 // Netd Callback handling
429 //
430
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700431 private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks {
432 @Override
San Mehat873f2142010-01-14 10:25:07 -0800433 public void onDaemonConnected() {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700434 // event is dispatched from internal NDC thread, so we prepare the
435 // daemon back on main thread.
436 if (mConnectedSignal != null) {
437 mConnectedSignal.countDown();
438 mConnectedSignal = null;
439 } else {
440 mMainHandler.post(new Runnable() {
441 @Override
442 public void run() {
443 prepareNativeDaemon();
444 }
445 });
446 }
San Mehat873f2142010-01-14 10:25:07 -0800447 }
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700448
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700449 @Override
San Mehat873f2142010-01-14 10:25:07 -0800450 public boolean onEvent(int code, String raw, String[] cooked) {
JP Abgrall12b933d2011-07-14 18:09:22 -0700451 switch (code) {
452 case NetdResponseCode.InterfaceChange:
453 /*
454 * a network interface change occured
455 * Format: "NNN Iface added <name>"
456 * "NNN Iface removed <name>"
457 * "NNN Iface changed <name> <up/down>"
458 * "NNN Iface linkstatus <name> <up/down>"
459 */
460 if (cooked.length < 4 || !cooked[1].equals("Iface")) {
461 throw new IllegalStateException(
462 String.format("Invalid event from daemon (%s)", raw));
463 }
464 if (cooked[2].equals("added")) {
465 notifyInterfaceAdded(cooked[3]);
466 return true;
467 } else if (cooked[2].equals("removed")) {
468 notifyInterfaceRemoved(cooked[3]);
469 return true;
470 } else if (cooked[2].equals("changed") && cooked.length == 5) {
471 notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
472 return true;
473 } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
474 notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
475 return true;
476 }
Robert Greenwalte3253922010-02-18 09:23:25 -0800477 throw new IllegalStateException(
478 String.format("Invalid event from daemon (%s)", raw));
JP Abgrall12b933d2011-07-14 18:09:22 -0700479 // break;
480 case NetdResponseCode.BandwidthControl:
481 /*
482 * Bandwidth control needs some attention
483 * Format: "NNN limit alert <alertName> <ifaceName>"
484 */
485 if (cooked.length < 5 || !cooked[1].equals("limit")) {
486 throw new IllegalStateException(
487 String.format("Invalid event from daemon (%s)", raw));
488 }
489 if (cooked[2].equals("alert")) {
490 notifyLimitReached(cooked[3], cooked[4]);
491 return true;
492 }
493 throw new IllegalStateException(
494 String.format("Invalid event from daemon (%s)", raw));
495 // break;
Haoyu Baidb3c8672012-06-20 14:29:57 -0700496 case NetdResponseCode.InterfaceClassActivity:
497 /*
498 * An network interface class state changed (active/idle)
499 * Format: "NNN IfaceClass <active/idle> <label>"
500 */
501 if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
502 throw new IllegalStateException(
503 String.format("Invalid event from daemon (%s)", raw));
504 }
505 boolean isActive = cooked[2].equals("active");
506 notifyInterfaceClassActivity(cooked[3], isActive);
507 return true;
508 // break;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900509 case NetdResponseCode.InterfaceAddressChange:
510 /*
511 * A network address change occurred
512 * Format: "NNN Address updated <addr> <iface> <flags> <scope>"
513 * "NNN Address removed <addr> <iface> <flags> <scope>"
514 */
515 String msg = String.format("Invalid event from daemon (%s)", raw);
516 if (cooked.length < 6 || !cooked[1].equals("Address")) {
517 throw new IllegalStateException(msg);
518 }
519
520 int flags, scope;
521 try {
522 flags = Integer.parseInt(cooked[5]);
523 scope = Integer.parseInt(cooked[6]);
524 } catch(NumberFormatException e) {
525 throw new IllegalStateException(msg);
526 }
527
528 if (cooked[2].equals("updated")) {
529 notifyAddressUpdated(cooked[3], cooked[4], flags, scope);
530 } else {
531 notifyAddressRemoved(cooked[3], cooked[4], flags, scope);
532 }
533 return true;
534 // break;
JP Abgrall12b933d2011-07-14 18:09:22 -0700535 default: break;
Robert Greenwalte3253922010-02-18 09:23:25 -0800536 }
537 return false;
San Mehat873f2142010-01-14 10:25:07 -0800538 }
539 }
540
San Mehated4fc8a2010-01-22 12:28:36 -0800541
San Mehat873f2142010-01-14 10:25:07 -0800542 //
543 // INetworkManagementService members
544 //
545
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800546 @Override
547 public String[] listInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800548 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700549 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800550 return NativeDaemonEvent.filterMessageList(
551 mConnector.executeForList("interface", "list"), InterfaceListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700552 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800553 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700554 }
San Mehated4fc8a2010-01-22 12:28:36 -0800555 }
556
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800557 @Override
558 public InterfaceConfiguration getInterfaceConfig(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800559 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800560
561 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700562 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800563 event = mConnector.execute("interface", "getcfg", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700564 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800565 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700566 }
San Mehated4fc8a2010-01-22 12:28:36 -0800567
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800568 event.checkCode(InterfaceGetCfgResult);
569
570 // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz flag1 flag2 flag3
571 final StringTokenizer st = new StringTokenizer(event.getMessage());
San Mehated4fc8a2010-01-22 12:28:36 -0800572
Kenny Roota80ce062010-06-01 13:23:53 -0700573 InterfaceConfiguration cfg;
San Mehated4fc8a2010-01-22 12:28:36 -0800574 try {
Kenny Roota80ce062010-06-01 13:23:53 -0700575 cfg = new InterfaceConfiguration();
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800576 cfg.setHardwareAddress(st.nextToken(" "));
Robert Greenwalted126402011-01-28 15:34:55 -0800577 InetAddress addr = null;
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800578 int prefixLength = 0;
Kenny Roota80ce062010-06-01 13:23:53 -0700579 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800580 addr = NetworkUtils.numericToInetAddress(st.nextToken());
Robert Greenwalte5903732011-02-22 16:00:42 -0800581 } catch (IllegalArgumentException iae) {
582 Slog.e(TAG, "Failed to parse ipaddr", iae);
Kenny Roota80ce062010-06-01 13:23:53 -0700583 }
584
585 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800586 prefixLength = Integer.parseInt(st.nextToken());
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800587 } catch (NumberFormatException nfe) {
588 Slog.e(TAG, "Failed to parse prefixLength", nfe);
Kenny Roota80ce062010-06-01 13:23:53 -0700589 }
Robert Greenwalt04808c22010-12-13 17:01:41 -0800590
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800591 cfg.setLinkAddress(new LinkAddress(addr, prefixLength));
592 while (st.hasMoreTokens()) {
593 cfg.setFlag(st.nextToken());
594 }
Kenny Roota80ce062010-06-01 13:23:53 -0700595 } catch (NoSuchElementException nsee) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800596 throw new IllegalStateException("Invalid response from daemon: " + event);
San Mehated4fc8a2010-01-22 12:28:36 -0800597 }
San Mehated4fc8a2010-01-22 12:28:36 -0800598 return cfg;
599 }
600
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800601 @Override
602 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800603 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800604 LinkAddress linkAddr = cfg.getLinkAddress();
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800605 if (linkAddr == null || linkAddr.getAddress() == null) {
606 throw new IllegalStateException("Null LinkAddress given");
Robert Greenwalted126402011-01-28 15:34:55 -0800607 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800608
609 final Command cmd = new Command("interface", "setcfg", iface,
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800610 linkAddr.getAddress().getHostAddress(),
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800611 linkAddr.getNetworkPrefixLength());
612 for (String flag : cfg.getFlags()) {
613 cmd.appendArg(flag);
614 }
615
Kenny Roota80ce062010-06-01 13:23:53 -0700616 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800617 mConnector.execute(cmd);
Kenny Roota80ce062010-06-01 13:23:53 -0700618 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800619 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700620 }
San Mehat873f2142010-01-14 10:25:07 -0800621 }
622
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800623 @Override
624 public void setInterfaceDown(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800625 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800626 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800627 ifcg.setInterfaceDown();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800628 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700629 }
630
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800631 @Override
632 public void setInterfaceUp(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800633 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800634 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800635 ifcg.setInterfaceUp();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800636 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700637 }
638
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800639 @Override
640 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800641 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sheriff73293612011-09-14 12:31:56 -0700642 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800643 mConnector.execute(
644 "interface", "ipv6privacyextensions", iface, enable ? "enable" : "disable");
Irfan Sheriff73293612011-09-14 12:31:56 -0700645 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800646 throw e.rethrowAsParcelableException();
Irfan Sheriff73293612011-09-14 12:31:56 -0700647 }
648 }
649
Irfan Sherifff5600612011-06-16 10:26:28 -0700650 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
651 IPv6 addresses on interface down, but we need to do full clean up here */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800652 @Override
653 public void clearInterfaceAddresses(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800654 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sherifff5600612011-06-16 10:26:28 -0700655 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800656 mConnector.execute("interface", "clearaddrs", iface);
Irfan Sherifff5600612011-06-16 10:26:28 -0700657 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800658 throw e.rethrowAsParcelableException();
Irfan Sherifff5600612011-06-16 10:26:28 -0700659 }
660 }
661
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800662 @Override
663 public void enableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800664 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700665 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800666 mConnector.execute("interface", "ipv6", iface, "enable");
repo sync7960d9f2011-09-29 12:40:02 -0700667 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800668 throw e.rethrowAsParcelableException();
repo sync7960d9f2011-09-29 12:40:02 -0700669 }
670 }
671
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800672 @Override
673 public void disableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800674 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700675 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800676 mConnector.execute("interface", "ipv6", iface, "disable");
repo sync7960d9f2011-09-29 12:40:02 -0700677 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800678 throw e.rethrowAsParcelableException();
repo sync7960d9f2011-09-29 12:40:02 -0700679 }
680 }
681
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800682 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700683 public void addRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800684 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700685 modifyRoute(interfaceName, ADD, route, DEFAULT);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700686 }
687
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800688 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700689 public void removeRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800690 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700691 modifyRoute(interfaceName, REMOVE, route, DEFAULT);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700692 }
693
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800694 @Override
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700695 public void addSecondaryRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800696 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700697 modifyRoute(interfaceName, ADD, route, SECONDARY);
698 }
699
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800700 @Override
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700701 public void removeSecondaryRoute(String interfaceName, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800702 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700703 modifyRoute(interfaceName, REMOVE, route, SECONDARY);
704 }
705
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800706 private void modifyRoute(String interfaceName, String action, RouteInfo route, String type) {
707 final Command cmd = new Command("interface", "route", action, interfaceName, type);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700708
709 // create triplet: dest-ip-addr prefixlength gateway-ip-addr
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800710 final LinkAddress la = route.getDestination();
711 cmd.appendArg(la.getAddress().getHostAddress());
712 cmd.appendArg(la.getNetworkPrefixLength());
713
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700714 if (route.getGateway() == null) {
715 if (la.getAddress() instanceof Inet4Address) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800716 cmd.appendArg("0.0.0.0");
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700717 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800718 cmd.appendArg("::0");
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700719 }
720 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800721 cmd.appendArg(route.getGateway().getHostAddress());
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700722 }
723
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800724 try {
725 mConnector.execute(cmd);
726 } catch (NativeDaemonConnectorException e) {
727 throw e.rethrowAsParcelableException();
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700728 }
729 }
730
731 private ArrayList<String> readRouteList(String filename) {
732 FileInputStream fstream = null;
733 ArrayList<String> list = new ArrayList<String>();
734
735 try {
736 fstream = new FileInputStream(filename);
737 DataInputStream in = new DataInputStream(fstream);
738 BufferedReader br = new BufferedReader(new InputStreamReader(in));
739 String s;
740
741 // throw away the title line
742
743 while (((s = br.readLine()) != null) && (s.length() != 0)) {
744 list.add(s);
745 }
746 } catch (IOException ex) {
747 // return current list, possibly empty
748 } finally {
749 if (fstream != null) {
750 try {
751 fstream.close();
752 } catch (IOException ex) {}
753 }
754 }
755
756 return list;
757 }
758
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800759 @Override
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700760 public RouteInfo[] getRoutes(String interfaceName) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800761 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700762 ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
763
764 // v4 routes listed as:
765 // iface dest-addr gateway-addr flags refcnt use metric netmask mtu window IRTT
766 for (String s : readRouteList("/proc/net/route")) {
767 String[] fields = s.split("\t");
768
769 if (fields.length > 7) {
770 String iface = fields[0];
771
772 if (interfaceName.equals(iface)) {
773 String dest = fields[1];
774 String gate = fields[2];
775 String flags = fields[3]; // future use?
776 String mask = fields[7];
777 try {
778 // address stored as a hex string, ex: 0014A8C0
779 InetAddress destAddr =
780 NetworkUtils.intToInetAddress((int)Long.parseLong(dest, 16));
781 int prefixLength =
782 NetworkUtils.netmaskIntToPrefixLength(
783 (int)Long.parseLong(mask, 16));
784 LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
785
786 // address stored as a hex string, ex 0014A8C0
787 InetAddress gatewayAddr =
788 NetworkUtils.intToInetAddress((int)Long.parseLong(gate, 16));
789
Wink Saville7b5fd052013-03-15 05:07:04 +0000790 RouteInfo route = new RouteInfo(linkAddress, gatewayAddr);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700791 routes.add(route);
792 } catch (Exception e) {
793 Log.e(TAG, "Error parsing route " + s + " : " + e);
794 continue;
795 }
796 }
797 }
798 }
799
800 // v6 routes listed as:
801 // dest-addr prefixlength ?? ?? gateway-addr ?? ?? ?? ?? iface
802 for (String s : readRouteList("/proc/net/ipv6_route")) {
803 String[]fields = s.split("\\s+");
804 if (fields.length > 9) {
805 String iface = fields[9].trim();
806 if (interfaceName.equals(iface)) {
807 String dest = fields[0];
808 String prefix = fields[1];
809 String gate = fields[4];
810
811 try {
812 // prefix length stored as a hex string, ex 40
813 int prefixLength = Integer.parseInt(prefix, 16);
814
815 // address stored as a 32 char hex string
816 // ex fe800000000000000000000000000000
817 InetAddress destAddr = NetworkUtils.hexToInet6Address(dest);
818 LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
819
820 InetAddress gateAddr = NetworkUtils.hexToInet6Address(gate);
821
Wink Saville7b5fd052013-03-15 05:07:04 +0000822 RouteInfo route = new RouteInfo(linkAddress, gateAddr);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700823 routes.add(route);
824 } catch (Exception e) {
825 Log.e(TAG, "Error parsing route " + s + " : " + e);
826 continue;
827 }
828 }
829 }
830 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800831 return routes.toArray(new RouteInfo[routes.size()]);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700832 }
833
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800834 @Override
San Mehat873f2142010-01-14 10:25:07 -0800835 public void shutdown() {
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800836 // TODO: remove from aidl if nobody calls externally
837 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800838
Joe Onorato8a9b2202010-02-26 18:56:32 -0800839 Slog.d(TAG, "Shutting down");
San Mehat873f2142010-01-14 10:25:07 -0800840 }
841
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800842 @Override
San Mehat873f2142010-01-14 10:25:07 -0800843 public boolean getIpForwardingEnabled() throws IllegalStateException{
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800844 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800845
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800846 final NativeDaemonEvent event;
Kenny Roota80ce062010-06-01 13:23:53 -0700847 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800848 event = mConnector.execute("ipfwd", "status");
Kenny Roota80ce062010-06-01 13:23:53 -0700849 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800850 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700851 }
San Mehat873f2142010-01-14 10:25:07 -0800852
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800853 // 211 Forwarding enabled
854 event.checkCode(IpFwdStatusResult);
855 return event.getMessage().endsWith("enabled");
San Mehat873f2142010-01-14 10:25:07 -0800856 }
857
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800858 @Override
859 public void setIpForwardingEnabled(boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800860 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800861 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800862 mConnector.execute("ipfwd", enable ? "enable" : "disable");
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800863 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800864 throw e.rethrowAsParcelableException();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800865 }
San Mehat873f2142010-01-14 10:25:07 -0800866 }
867
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800868 @Override
869 public void startTethering(String[] dhcpRange) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800870 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700871 // cmd is "tether start first_start first_stop second_start second_stop ..."
872 // an odd number of addrs will fail
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800873
874 final Command cmd = new Command("tether", "start");
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700875 for (String d : dhcpRange) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800876 cmd.appendArg(d);
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -0700877 }
Kenny Roota80ce062010-06-01 13:23:53 -0700878
879 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800880 mConnector.execute(cmd);
Kenny Roota80ce062010-06-01 13:23:53 -0700881 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800882 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700883 }
San Mehat873f2142010-01-14 10:25:07 -0800884 }
885
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800886 @Override
887 public void stopTethering() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800888 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700889 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800890 mConnector.execute("tether", "stop");
Kenny Roota80ce062010-06-01 13:23:53 -0700891 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800892 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700893 }
San Mehat873f2142010-01-14 10:25:07 -0800894 }
895
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800896 @Override
897 public boolean isTetheringStarted() {
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("tether", "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 // 210 Tethering services started
908 event.checkCode(TetherStatusResult);
909 return event.getMessage().endsWith("started");
San Mehat873f2142010-01-14 10:25:07 -0800910 }
Matthew Xiefe19f122012-07-12 16:03:32 -0700911
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800912 @Override
913 public void tetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800914 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700915 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800916 mConnector.execute("tether", "interface", "add", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700917 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800918 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700919 }
San Mehat873f2142010-01-14 10:25:07 -0800920 }
921
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800922 @Override
San Mehat873f2142010-01-14 10:25:07 -0800923 public void untetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800924 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700925 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800926 mConnector.execute("tether", "interface", "remove", iface);
Kenny Roota80ce062010-06-01 13:23:53 -0700927 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800928 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700929 }
San Mehat873f2142010-01-14 10:25:07 -0800930 }
931
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800932 @Override
933 public String[] listTetheredInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800934 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700935 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800936 return NativeDaemonEvent.filterMessageList(
937 mConnector.executeForList("tether", "interface", "list"),
938 TetherInterfaceListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700939 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800940 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700941 }
San Mehat873f2142010-01-14 10:25:07 -0800942 }
943
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800944 @Override
945 public void setDnsForwarders(String[] dns) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800946 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800947
948 final Command cmd = new Command("tether", "dns", "set");
949 for (String s : dns) {
950 cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
951 }
952
San Mehat873f2142010-01-14 10:25:07 -0800953 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800954 mConnector.execute(cmd);
955 } catch (NativeDaemonConnectorException e) {
956 throw e.rethrowAsParcelableException();
San Mehat873f2142010-01-14 10:25:07 -0800957 }
958 }
959
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800960 @Override
961 public String[] getDnsForwarders() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800962 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700963 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800964 return NativeDaemonEvent.filterMessageList(
965 mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult);
Kenny Roota80ce062010-06-01 13:23:53 -0700966 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800967 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -0700968 }
San Mehat873f2142010-01-14 10:25:07 -0800969 }
970
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800971 private void modifyNat(String action, String internalInterface, String externalInterface)
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700972 throws SocketException {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800973 final Command cmd = new Command("nat", action, internalInterface, externalInterface);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700974
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800975 final NetworkInterface internalNetworkInterface = NetworkInterface.getByName(
976 internalInterface);
Robert Greenwalte83d1812011-11-21 14:44:39 -0800977 if (internalNetworkInterface == null) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800978 cmd.appendArg("0");
Robert Greenwalte83d1812011-11-21 14:44:39 -0800979 } else {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800980 Collection<InterfaceAddress> interfaceAddresses = internalNetworkInterface
981 .getInterfaceAddresses();
982 cmd.appendArg(interfaceAddresses.size());
Robert Greenwalte83d1812011-11-21 14:44:39 -0800983 for (InterfaceAddress ia : interfaceAddresses) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800984 InetAddress addr = NetworkUtils.getNetworkPart(
985 ia.getAddress(), ia.getNetworkPrefixLength());
986 cmd.appendArg(addr.getHostAddress() + "/" + ia.getNetworkPrefixLength());
Robert Greenwalte83d1812011-11-21 14:44:39 -0800987 }
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700988 }
989
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800990 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800991 mConnector.execute(cmd);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800992 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -0800993 throw e.rethrowAsParcelableException();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800994 }
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700995 }
996
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800997 @Override
998 public void enableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800999 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001000 try {
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001001 modifyNat("enable", internalInterface, externalInterface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001002 } catch (SocketException e) {
1003 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001004 }
San Mehat873f2142010-01-14 10:25:07 -08001005 }
1006
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001007 @Override
1008 public void disableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001009 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001010 try {
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001011 modifyNat("disable", internalInterface, externalInterface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001012 } catch (SocketException e) {
1013 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001014 }
San Mehat873f2142010-01-14 10:25:07 -08001015 }
San Mehat72759df2010-01-19 13:50:37 -08001016
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001017 @Override
1018 public String[] listTtys() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001019 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001020 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001021 return NativeDaemonEvent.filterMessageList(
1022 mConnector.executeForList("list_ttys"), TtyListResult);
Kenny Roota80ce062010-06-01 13:23:53 -07001023 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001024 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001025 }
San Mehat72759df2010-01-19 13:50:37 -08001026 }
1027
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001028 @Override
1029 public void attachPppd(
1030 String tty, String localAddr, String remoteAddr, String dns1Addr, String dns2Addr) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001031 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat72759df2010-01-19 13:50:37 -08001032 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001033 mConnector.execute("pppd", "attach", tty,
Robert Greenwalte5903732011-02-22 16:00:42 -08001034 NetworkUtils.numericToInetAddress(localAddr).getHostAddress(),
1035 NetworkUtils.numericToInetAddress(remoteAddr).getHostAddress(),
1036 NetworkUtils.numericToInetAddress(dns1Addr).getHostAddress(),
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001037 NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress());
Kenny Roota80ce062010-06-01 13:23:53 -07001038 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001039 throw e.rethrowAsParcelableException();
San Mehat72759df2010-01-19 13:50:37 -08001040 }
1041 }
1042
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001043 @Override
1044 public void detachPppd(String tty) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001045 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001046 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001047 mConnector.execute("pppd", "detach", tty);
Kenny Roota80ce062010-06-01 13:23:53 -07001048 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001049 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001050 }
San Mehat72759df2010-01-19 13:50:37 -08001051 }
Robert Greenwaltce1200d2010-02-18 11:25:54 -08001052
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001053 @Override
1054 public void startAccessPoint(
Irfan Sheriff90542752012-06-19 15:44:35 -07001055 WifiConfiguration wifiConfig, String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001056 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001057 try {
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001058 wifiFirmwareReload(wlanIface, "AP");
Kenny Roota80ce062010-06-01 13:23:53 -07001059 if (wifiConfig == null) {
Irfan Sheriff90542752012-06-19 15:44:35 -07001060 mConnector.execute("softap", "set", wlanIface);
Kenny Roota80ce062010-06-01 13:23:53 -07001061 } else {
Irfan Sheriff90542752012-06-19 15:44:35 -07001062 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
Dmitry Shmidt28dd15b2013-06-10 14:37:08 -07001063 "broadcast", "6", getSecurityType(wifiConfig),
Kenny Root36062542013-06-10 11:09:28 -07001064 new SensitiveArg(wifiConfig.preSharedKey));
Kenny Roota80ce062010-06-01 13:23:53 -07001065 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001066 mConnector.execute("softap", "startap");
Kenny Roota80ce062010-06-01 13:23:53 -07001067 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001068 throw e.rethrowAsParcelableException();
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -08001069 }
Irfan Sheriff5321aef2010-02-12 12:35:59 -08001070 }
1071
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001072 private static String getSecurityType(WifiConfiguration wifiConfig) {
Irfan Sheriffec8d23a2011-02-16 17:00:33 -08001073 switch (wifiConfig.getAuthType()) {
1074 case KeyMgmt.WPA_PSK:
1075 return "wpa-psk";
1076 case KeyMgmt.WPA2_PSK:
1077 return "wpa2-psk";
1078 default:
1079 return "open";
1080 }
1081 }
1082
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001083 /* @param mode can be "AP", "STA" or "P2P" */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001084 @Override
1085 public void wifiFirmwareReload(String wlanIface, String mode) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001086 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001087 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001088 mConnector.execute("softap", "fwreload", wlanIface, mode);
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001089 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001090 throw e.rethrowAsParcelableException();
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001091 }
1092 }
1093
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001094 @Override
1095 public void stopAccessPoint(String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001096 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001097 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001098 mConnector.execute("softap", "stopap");
Irfan Sheriffcb30b222011-07-29 20:54:52 -07001099 wifiFirmwareReload(wlanIface, "STA");
Kenny Roota80ce062010-06-01 13:23:53 -07001100 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001101 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001102 }
Irfan Sheriff5321aef2010-02-12 12:35:59 -08001103 }
1104
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001105 @Override
Irfan Sheriff90542752012-06-19 15:44:35 -07001106 public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001107 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001108 try {
1109 if (wifiConfig == null) {
Irfan Sheriff90542752012-06-19 15:44:35 -07001110 mConnector.execute("softap", "set", wlanIface);
Kenny Roota80ce062010-06-01 13:23:53 -07001111 } else {
Irfan Sheriff90542752012-06-19 15:44:35 -07001112 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
Dmitry Shmidt28dd15b2013-06-10 14:37:08 -07001113 "broadcast", "6", getSecurityType(wifiConfig),
Kenny Root36062542013-06-10 11:09:28 -07001114 new SensitiveArg(wifiConfig.preSharedKey));
Kenny Roota80ce062010-06-01 13:23:53 -07001115 }
1116 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001117 throw e.rethrowAsParcelableException();
Irfan Sheriffc2f54c22010-03-18 14:02:22 -07001118 }
1119 }
San Mehat91cac642010-03-31 14:31:36 -07001120
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001121 @Override
Haoyu Bai04124232012-06-28 15:26:19 -07001122 public void addIdleTimer(String iface, int timeout, String label) {
1123 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1124
1125 if (DBG) Slog.d(TAG, "Adding idletimer");
1126
1127 synchronized (mIdleTimerLock) {
1128 IdleTimerParams params = mActiveIdleTimers.get(iface);
1129 if (params != null) {
1130 // the interface already has idletimer, update network count
1131 params.networkCount++;
1132 return;
1133 }
1134
1135 try {
1136 mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
1137 } catch (NativeDaemonConnectorException e) {
1138 throw e.rethrowAsParcelableException();
1139 }
1140 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
1141 }
1142 }
1143
1144 @Override
1145 public void removeIdleTimer(String iface) {
1146 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1147
1148 if (DBG) Slog.d(TAG, "Removing idletimer");
1149
1150 synchronized (mIdleTimerLock) {
1151 IdleTimerParams params = mActiveIdleTimers.get(iface);
1152 if (params == null || --(params.networkCount) > 0) {
1153 return;
1154 }
1155
1156 try {
1157 mConnector.execute("idletimer", "remove", iface,
1158 Integer.toString(params.timeout), params.label);
1159 } catch (NativeDaemonConnectorException e) {
1160 throw e.rethrowAsParcelableException();
1161 }
1162 mActiveIdleTimers.remove(iface);
1163 }
1164 }
1165
1166 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001167 public NetworkStats getNetworkStatsSummaryDev() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001168 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001169 try {
1170 return mStatsFactory.readNetworkStatsSummaryDev();
1171 } catch (IOException e) {
1172 throw new IllegalStateException(e);
1173 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001174 }
1175
1176 @Override
1177 public NetworkStats getNetworkStatsSummaryXt() {
1178 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001179 try {
1180 return mStatsFactory.readNetworkStatsSummaryXt();
1181 } catch (IOException e) {
1182 throw new IllegalStateException(e);
1183 }
Jeff Sharkeyae2c1812011-10-04 13:11:40 -07001184 }
1185
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001186 @Override
Jeff Sharkey9a13f362011-04-26 16:25:36 -07001187 public NetworkStats getNetworkStatsDetail() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001188 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001189 try {
1190 return mStatsFactory.readNetworkStatsDetail(UID_ALL);
1191 } catch (IOException e) {
1192 throw new IllegalStateException(e);
1193 }
San Mehat91cac642010-03-31 14:31:36 -07001194 }
1195
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001196 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001197 public void setInterfaceQuota(String iface, long quotaBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001198 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001199
Jeff Sharkey350083e2011-06-29 10:45:16 -07001200 // silently discard when control disabled
1201 // TODO: eventually migrate to be always enabled
1202 if (!mBandwidthControlEnabled) return;
1203
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001204 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001205 if (mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001206 throw new IllegalStateException("iface " + iface + " already has quota");
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001207 }
1208
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001209 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001210 // TODO: support quota shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001211 mConnector.execute("bandwidth", "setiquota", iface, quotaBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001212 mActiveQuotas.put(iface, quotaBytes);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001213 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001214 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001215 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001216 }
1217 }
1218
1219 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001220 public void removeInterfaceQuota(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001221 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001222
Jeff Sharkey350083e2011-06-29 10:45:16 -07001223 // silently discard when control disabled
1224 // TODO: eventually migrate to be always enabled
1225 if (!mBandwidthControlEnabled) return;
1226
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001227 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001228 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001229 // TODO: eventually consider throwing
1230 return;
1231 }
1232
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001233 mActiveQuotas.remove(iface);
1234 mActiveAlerts.remove(iface);
Jeff Sharkey38ddeaa2011-11-08 13:04:22 -08001235
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001236 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001237 // TODO: support quota shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001238 mConnector.execute("bandwidth", "removeiquota", iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001239 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001240 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001241 }
1242 }
1243 }
1244
1245 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001246 public void setInterfaceAlert(String iface, long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001247 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001248
1249 // silently discard when control disabled
1250 // TODO: eventually migrate to be always enabled
1251 if (!mBandwidthControlEnabled) return;
1252
1253 // quick sanity check
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001254 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001255 throw new IllegalStateException("setting alert requires existing quota on iface");
1256 }
1257
1258 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001259 if (mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001260 throw new IllegalStateException("iface " + iface + " already has alert");
1261 }
1262
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001263 try {
1264 // TODO: support alert shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001265 mConnector.execute("bandwidth", "setinterfacealert", iface, alertBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001266 mActiveAlerts.put(iface, alertBytes);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001267 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001268 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001269 }
1270 }
1271 }
1272
1273 @Override
1274 public void removeInterfaceAlert(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001275 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001276
1277 // silently discard when control disabled
1278 // TODO: eventually migrate to be always enabled
1279 if (!mBandwidthControlEnabled) return;
1280
1281 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001282 if (!mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001283 // TODO: eventually consider throwing
1284 return;
1285 }
1286
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001287 try {
1288 // TODO: support alert shared across interfaces
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001289 mConnector.execute("bandwidth", "removeinterfacealert", iface);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001290 mActiveAlerts.remove(iface);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001291 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001292 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001293 }
1294 }
1295 }
1296
1297 @Override
1298 public void setGlobalAlert(long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001299 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001300
1301 // silently discard when control disabled
1302 // TODO: eventually migrate to be always enabled
1303 if (!mBandwidthControlEnabled) return;
1304
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001305 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001306 mConnector.execute("bandwidth", "setglobalalert", alertBytes);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001307 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001308 throw e.rethrowAsParcelableException();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001309 }
1310 }
1311
1312 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001313 public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001314 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001315
Jeff Sharkey350083e2011-06-29 10:45:16 -07001316 // silently discard when control disabled
1317 // TODO: eventually migrate to be always enabled
1318 if (!mBandwidthControlEnabled) return;
1319
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001320 synchronized (mQuotaLock) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001321 final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
1322 if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
1323 // TODO: eventually consider throwing
1324 return;
1325 }
1326
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001327 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001328 mConnector.execute("bandwidth",
1329 rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001330 if (rejectOnQuotaInterfaces) {
1331 mUidRejectOnQuota.put(uid, true);
1332 } else {
1333 mUidRejectOnQuota.delete(uid);
1334 }
1335 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001336 throw e.rethrowAsParcelableException();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001337 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001338 }
1339 }
1340
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001341 @Override
1342 public boolean isBandwidthControlEnabled() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001343 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001344 return mBandwidthControlEnabled;
1345 }
1346
1347 @Override
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001348 public NetworkStats getNetworkStatsUidDetail(int uid) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001349 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001350 try {
1351 return mStatsFactory.readNetworkStatsDetail(uid);
1352 } catch (IOException e) {
1353 throw new IllegalStateException(e);
1354 }
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001355 }
1356
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001357 @Override
1358 public NetworkStats getNetworkStatsTethering(String[] ifacePairs) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001359 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001360
1361 if (ifacePairs.length % 2 != 0) {
1362 throw new IllegalArgumentException(
1363 "unexpected ifacePairs; length=" + ifacePairs.length);
1364 }
1365
1366 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
1367 for (int i = 0; i < ifacePairs.length; i += 2) {
1368 final String ifaceIn = ifacePairs[i];
1369 final String ifaceOut = ifacePairs[i + 1];
1370 if (ifaceIn != null && ifaceOut != null) {
1371 stats.combineValues(getNetworkStatsTethering(ifaceIn, ifaceOut));
1372 }
1373 }
1374 return stats;
1375 }
1376
1377 private NetworkStats.Entry getNetworkStatsTethering(String ifaceIn, String ifaceOut) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001378 final NativeDaemonEvent event;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001379 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001380 event = mConnector.execute("bandwidth", "gettetherstats", ifaceIn, ifaceOut);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001381 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001382 throw e.rethrowAsParcelableException();
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001383 }
1384
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001385 event.checkCode(TetheringStatsResult);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001386
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001387 // 221 ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
1388 final StringTokenizer tok = new StringTokenizer(event.getMessage());
1389 tok.nextToken();
1390 tok.nextToken();
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001391
1392 try {
1393 final NetworkStats.Entry entry = new NetworkStats.Entry();
1394 entry.iface = ifaceIn;
Jeff Sharkey905b5892011-09-30 15:19:49 -07001395 entry.uid = UID_TETHERING;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001396 entry.set = SET_DEFAULT;
1397 entry.tag = TAG_NONE;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001398 entry.rxBytes = Long.parseLong(tok.nextToken());
1399 entry.rxPackets = Long.parseLong(tok.nextToken());
1400 entry.txBytes = Long.parseLong(tok.nextToken());
1401 entry.txPackets = Long.parseLong(tok.nextToken());
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001402 return entry;
1403 } catch (NumberFormatException e) {
1404 throw new IllegalStateException(
1405 "problem parsing tethering stats for " + ifaceIn + " " + ifaceOut + ": " + e);
1406 }
1407 }
1408
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001409 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001410 public void setDefaultInterfaceForDns(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001411 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001412 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001413 mConnector.execute("resolver", "setdefaultif", iface);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001414 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001415 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001416 }
1417 }
1418
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001419 @Override
Robert Greenwalt8058f622012-11-09 10:52:27 -08001420 public void setDnsServersForInterface(String iface, String[] servers, String domains) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001421 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001422
Robert Greenwalt8058f622012-11-09 10:52:27 -08001423 final Command cmd = new Command("resolver", "setifdns", iface,
1424 (domains == null ? "" : domains));
1425
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001426 for (String s : servers) {
1427 InetAddress a = NetworkUtils.numericToInetAddress(s);
1428 if (a.isAnyLocalAddress() == false) {
1429 cmd.appendArg(a.getHostAddress());
Mattias Falk7475c0c2011-04-04 16:10:36 +02001430 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001431 }
1432
1433 try {
1434 mConnector.execute(cmd);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001435 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001436 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001437 }
1438 }
1439
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001440 @Override
Chad Brubaker3277620a2013-06-12 13:37:30 -07001441 public void setUidRangeRoute(String iface, int uid_start, int uid_end) {
1442 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1443 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001444 mConnector.execute("interface", "fwmark",
Chad Brubaker3277620a2013-06-12 13:37:30 -07001445 "uid", "add", iface, uid_start, uid_end);
1446 } catch (NativeDaemonConnectorException e) {
1447 throw e.rethrowAsParcelableException();
1448 }
1449 }
1450
1451 @Override
1452 public void clearUidRangeRoute(String iface, int uid_start, int uid_end) {
1453 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1454 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001455 mConnector.execute("interface", "fwmark",
Chad Brubaker3277620a2013-06-12 13:37:30 -07001456 "uid", "remove", iface, uid_start, uid_end);
1457 } catch (NativeDaemonConnectorException e) {
1458 throw e.rethrowAsParcelableException();
1459 }
1460 }
1461
1462 @Override
1463 public void setMarkedForwarding(String iface) {
1464 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1465 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001466 mConnector.execute("interface", "fwmark", "rule", "add", iface);
Chad Brubaker3277620a2013-06-12 13:37:30 -07001467 } catch (NativeDaemonConnectorException e) {
1468 throw e.rethrowAsParcelableException();
1469 }
1470 }
1471
1472 @Override
1473 public void clearMarkedForwarding(String iface) {
1474 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1475 try {
Chad Brubakercca54c42013-06-27 17:41:38 -07001476 mConnector.execute("interface", "fwmark", "rule", "remove", iface);
1477 } catch (NativeDaemonConnectorException e) {
1478 throw e.rethrowAsParcelableException();
1479 }
1480 }
1481
1482 @Override
1483 public int getMarkForUid(int uid) {
1484 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1485 final NativeDaemonEvent event;
1486 try {
1487 event = mConnector.execute("interface", "fwmark", "get", "mark", uid);
1488 } catch (NativeDaemonConnectorException e) {
1489 throw e.rethrowAsParcelableException();
1490 }
1491 event.checkCode(GetMarkResult);
1492 return Integer.parseInt(event.getMessage());
1493 }
1494
1495 @Override
1496 public int getMarkForProtect() {
1497 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1498 final NativeDaemonEvent event;
1499 try {
1500 event = mConnector.execute("interface", "fwmark", "get", "protect");
1501 } catch (NativeDaemonConnectorException e) {
1502 throw e.rethrowAsParcelableException();
1503 }
1504 event.checkCode(GetMarkResult);
1505 return Integer.parseInt(event.getMessage());
1506 }
1507
1508 @Override
1509 public void setMarkedForwardingRoute(String iface, RouteInfo route) {
1510 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1511 try {
1512 LinkAddress dest = route.getDestination();
1513 mConnector.execute("interface", "fwmark", "route", "add", iface,
1514 dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
1515 } catch (NativeDaemonConnectorException e) {
1516 throw e.rethrowAsParcelableException();
1517 }
1518 }
1519
1520 @Override
1521 public void clearMarkedForwardingRoute(String iface, RouteInfo route) {
1522 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1523 try {
1524 LinkAddress dest = route.getDestination();
1525 mConnector.execute("interface", "fwmark", "route", "remove", iface,
1526 dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
Chad Brubaker3277620a2013-06-12 13:37:30 -07001527 } catch (NativeDaemonConnectorException e) {
1528 throw e.rethrowAsParcelableException();
1529 }
1530 }
1531
1532 @Override
Chad Brubakerf336d722013-07-15 16:34:04 -07001533 public void setHostExemption(LinkAddress host) {
1534 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1535 try {
1536 mConnector.execute("interface", "fwmark", "exempt", "add", host);
1537 } catch (NativeDaemonConnectorException e) {
1538 throw e.rethrowAsParcelableException();
1539 }
1540 }
1541
1542 @Override
1543 public void clearHostExemption(LinkAddress host) {
1544 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1545 try {
1546 mConnector.execute("interface", "fwmark", "exempt", "remove", host);
1547 } catch (NativeDaemonConnectorException e) {
1548 throw e.rethrowAsParcelableException();
1549 }
1550 }
1551
1552 @Override
Chad Brubaker3277620a2013-06-12 13:37:30 -07001553 public void setDnsInterfaceForUidRange(String iface, int uid_start, int uid_end) {
1554 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1555 try {
1556 mConnector.execute("resolver", "setifaceforuidrange", iface, uid_start, uid_end);
1557 } catch (NativeDaemonConnectorException e) {
1558 throw e.rethrowAsParcelableException();
1559 }
1560 }
1561
1562 @Override
1563 public void clearDnsInterfaceForUidRange(int uid_start, int uid_end) {
1564 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1565 try {
1566 mConnector.execute("resolver", "clearifaceforuidrange", uid_start, uid_end);
1567 } catch (NativeDaemonConnectorException e) {
1568 throw e.rethrowAsParcelableException();
1569 }
1570 }
1571
1572 @Override
1573 public void clearDnsInterfaceMaps() {
1574 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1575 try {
1576 mConnector.execute("resolver", "clearifacemapping");
1577 } catch (NativeDaemonConnectorException e) {
1578 throw e.rethrowAsParcelableException();
1579 }
1580 }
1581
1582
1583 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001584 public void flushDefaultDnsCache() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001585 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001586 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001587 mConnector.execute("resolver", "flushdefaultif");
Mattias Falk7475c0c2011-04-04 16:10:36 +02001588 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001589 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001590 }
1591 }
1592
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001593 @Override
1594 public void flushInterfaceDnsCache(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001595 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001596 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001597 mConnector.execute("resolver", "flushif", iface);
Mattias Falk7475c0c2011-04-04 16:10:36 +02001598 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001599 throw e.rethrowAsParcelableException();
Mattias Falk7475c0c2011-04-04 16:10:36 +02001600 }
1601 }
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -07001602
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001603 @Override
1604 public void setFirewallEnabled(boolean enabled) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001605 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001606 try {
1607 mConnector.execute("firewall", enabled ? "enable" : "disable");
1608 mFirewallEnabled = enabled;
1609 } catch (NativeDaemonConnectorException e) {
1610 throw e.rethrowAsParcelableException();
1611 }
1612 }
1613
1614 @Override
1615 public boolean isFirewallEnabled() {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001616 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001617 return mFirewallEnabled;
1618 }
1619
1620 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001621 public void setFirewallInterfaceRule(String iface, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001622 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001623 Preconditions.checkState(mFirewallEnabled);
1624 final String rule = allow ? ALLOW : DENY;
1625 try {
1626 mConnector.execute("firewall", "set_interface_rule", iface, rule);
1627 } catch (NativeDaemonConnectorException e) {
1628 throw e.rethrowAsParcelableException();
1629 }
1630 }
1631
1632 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001633 public void setFirewallEgressSourceRule(String addr, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001634 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001635 Preconditions.checkState(mFirewallEnabled);
1636 final String rule = allow ? ALLOW : DENY;
1637 try {
1638 mConnector.execute("firewall", "set_egress_source_rule", addr, rule);
1639 } catch (NativeDaemonConnectorException e) {
1640 throw e.rethrowAsParcelableException();
1641 }
1642 }
1643
1644 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001645 public void setFirewallEgressDestRule(String addr, int port, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001646 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001647 Preconditions.checkState(mFirewallEnabled);
1648 final String rule = allow ? ALLOW : DENY;
1649 try {
1650 mConnector.execute("firewall", "set_egress_dest_rule", addr, port, rule);
1651 } catch (NativeDaemonConnectorException e) {
1652 throw e.rethrowAsParcelableException();
1653 }
1654 }
1655
1656 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001657 public void setFirewallUidRule(int uid, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001658 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001659 Preconditions.checkState(mFirewallEnabled);
1660 final String rule = allow ? ALLOW : DENY;
1661 try {
1662 mConnector.execute("firewall", "set_uid_rule", uid, rule);
1663 } catch (NativeDaemonConnectorException e) {
1664 throw e.rethrowAsParcelableException();
1665 }
1666 }
1667
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001668 private static void enforceSystemUid() {
1669 final int uid = Binder.getCallingUid();
1670 if (uid != Process.SYSTEM_UID) {
1671 throw new SecurityException("Only available to AID_SYSTEM");
1672 }
1673 }
1674
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001675 @Override
Mattias Falk8b47b362011-08-23 14:15:13 +02001676 public void setDnsInterfaceForPid(String iface, int pid) throws IllegalStateException {
1677 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1678 try {
Jeff Sharkey0c232f52013-02-13 11:27:24 -08001679 mConnector.execute("resolver", "setifaceforpid", iface, pid);
Mattias Falk8b47b362011-08-23 14:15:13 +02001680 } catch (NativeDaemonConnectorException e) {
1681 throw new IllegalStateException(
1682 "Error communicating with native deamon to set interface for pid" + iface, e);
1683 }
1684 }
1685
1686 @Override
1687 public void clearDnsInterfaceForPid(int pid) throws IllegalStateException {
1688 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1689 try {
Jeff Sharkey0c232f52013-02-13 11:27:24 -08001690 mConnector.execute("resolver", "clearifaceforpid", pid);
Mattias Falk8b47b362011-08-23 14:15:13 +02001691 } catch (NativeDaemonConnectorException e) {
1692 throw new IllegalStateException(
1693 "Error communicating with native deamon to clear interface for pid " + pid, e);
1694 }
1695 }
1696
Lorenzo Colitti79751842013-02-28 16:16:03 +09001697 @Override
1698 public void startClatd(String interfaceName) throws IllegalStateException {
1699 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1700
1701 try {
1702 mConnector.execute("clatd", "start", interfaceName);
1703 } catch (NativeDaemonConnectorException e) {
1704 throw e.rethrowAsParcelableException();
1705 }
1706 }
1707
1708 @Override
1709 public void stopClatd() throws IllegalStateException {
1710 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1711
1712 try {
1713 mConnector.execute("clatd", "stop");
1714 } catch (NativeDaemonConnectorException e) {
1715 throw e.rethrowAsParcelableException();
1716 }
1717 }
1718
1719 @Override
1720 public boolean isClatdStarted() {
1721 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1722
1723 final NativeDaemonEvent event;
1724 try {
1725 event = mConnector.execute("clatd", "status");
1726 } catch (NativeDaemonConnectorException e) {
1727 throw e.rethrowAsParcelableException();
1728 }
1729
1730 event.checkCode(ClatdStatusResult);
1731 return event.getMessage().endsWith("started");
1732 }
1733
Mattias Falk8b47b362011-08-23 14:15:13 +02001734 /** {@inheritDoc} */
Jeff Sharkey7b4596f2013-02-25 10:55:29 -08001735 @Override
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -07001736 public void monitor() {
1737 if (mConnector != null) {
1738 mConnector.monitor();
1739 }
1740 }
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001741
1742 @Override
1743 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1744 mContext.enforceCallingOrSelfPermission(DUMP, TAG);
1745
Robert Greenwalt470fd722012-01-18 12:51:15 -08001746 pw.println("NetworkManagementService NativeDaemonConnector Log:");
1747 mConnector.dump(fd, pw, args);
1748 pw.println();
1749
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001750 pw.print("Bandwidth control enabled: "); pw.println(mBandwidthControlEnabled);
1751
1752 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001753 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
1754 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001755 }
1756
1757 synchronized (mUidRejectOnQuota) {
1758 pw.print("UID reject on quota ifaces: [");
1759 final int size = mUidRejectOnQuota.size();
1760 for (int i = 0; i < size; i++) {
1761 pw.print(mUidRejectOnQuota.keyAt(i));
1762 if (i < size - 1) pw.print(",");
1763 }
1764 pw.println("]");
1765 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001766
1767 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001768 }
San Mehat873f2142010-01-14 10:25:07 -08001769}