Android5.0网络策略导致PPPOE无法正常上网

您所在的位置:网站首页 网络策略服务无法启动 Android5.0网络策略导致PPPOE无法正常上网

Android5.0网络策略导致PPPOE无法正常上网

#Android5.0网络策略导致PPPOE无法正常上网| 来源: 网络整理| 查看: 265

logcat -s NetworkSettingsActivity EthernetImpl PppoeManager PppoeServiceImpl PppoeNetworkFactory pppd pppoe ConnectivityService

一、问题描述

应用程序API

frameworks/base/core/java/android/net/pppoe/PppoeManager.java

public void connectPppoe(final String account, final String password) { connectPppoe(account, password, "eth0"); }

转载:linux ppp pppoe

1.在Android5.0系统上移植rp-pppoe后,并打开内核中所有相关ppp的选项;运行如下:

pppoe -d  //发现pppoe-server设备,mac地址如下

21258:d8:49:0b:8b:81:5f

通过pppd认证连接:

pppd pty "pppoe -I eth0" user *********** password ******

2.结果

busybox ifconfig

eth0 Link encap:Ethernet HWaddr 00:44:22:11:44:11 inet addr:192.168.1.6 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: fe80::244:22ff:fe11:4411/64 Scope:Link UP BROADCAST RUNNING ALLMULTI MULTICAST MTU:1500 Metric:1 RX packets:646 errors:0 dropped:126 overruns:0 frame:0 TX packets:994 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:30 RX bytes:410306 (400.6 KiB) TX bytes:147322 (143.8 KiB) Interrupt:201 Base address:0x4000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:14 errors:0 dropped:0 overruns:0 frame:0 TX packets:14 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:916 (916.0 B) TX bytes:916 (916.0 B) ppp0 Link encap:Point-to-Point Protocol inet addr:117.36.23.177 P-t-P:117.36.20.1 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1492 Metric:1 RX packets:15 errors:0 dropped:0 overruns:0 frame:0 TX packets:80 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:1098 (1.0 KiB) TX bytes:8191 (7.9 KiB)ppp0正确获取。

busybox route -e

Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface default 117.36.23.177 0.0.0.0 UG 0 0 0 ppp0 default * 0.0.0.0 U 0 0 0 ppp0 117.36.20.1 * 255.255.255.255 UH 0 0 0 ppp0 192.168.1.0 * 255.255.255.0 U 0 0 0 eth0默认网关为ppp0的IP地址;也有到达拨号路由器117.36.20.1的路由。

3.错误问题

ping不通路由器网关117.36.20.1,ping不通百度。

ping www.baidu.com

busybox traceroute www.baidu.com traceroute to www.baidu.com (180.97.33.107), 30 hops max, 38 byte packets 1 192.168.1.1 (192.168.1.1) 5.261 ms 5.137 ms 5.271 ms 2 * * * 3 * *

二、问题分析

从上边看出百度的IP180.97.33.107拿的是正确的;可以排除DNS问题。

起初怀疑是route问题;删除192.168.1.0(busybox route del -net 192.168.1.0 netmask 255.255.255.0)的route并配置其他路由(busybox route add -net 117.36.20.1 gw 117.36.23.177 netmask 255.255.0.0 ppp0)以后,问题还是存在。

后来通过ping -I ppp0 www.baidu.com,通了。

我们可以将问题定位为;网络数据在PPPOE连接以后;没有切换到PPPOE,而是还在Ethernet上。

三、Android网络切换分析

这里我们必须要通过调试Android5.0系统的网络切换策略来处理了。

1.Android系统支持的网络类型xml

frameworks/base/services/core/java/com/android/server/ConnectivityService.java

public ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager) { ...... String[] naStrings = context.getResources().getStringArray(com.android.internal.R.array.networkAttributes); ...... }

如下资源文件,也就是system/framework/framework-res.apk

frameworks/base/core/res/res/values/config.xml

"wifi,1,1,1,-1,true" "ethernet,9,9,9,-1,true" "pppoe,18,18,1,-1,true" 上处xml中该值应该为18;系统Code错误写成15,这个定义需要如下相对应:

frameworks/base/core/java/android/net/ConnectivityManager.java

public class ConnectivityManager { ...... public static final int TYPE_WIFI = 1; public static final int TYPE_ETHERNET = 9; public static final int TYPE_PPPOE = 18; public static final int MAX_RADIO_TYPE = TYPE_PPPOE; public static final int MAX_NETWORK_TYPE = TYPE_PPPOE; public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI; ...... }至此;系统可以通过配置文件去支持PPPOE。

2.PPPOE网络服务启动

Android系统中管理网络策略的主体为ConnectivityService,因此、需要PppoeService向其注册监听信息。

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer { private static final String PPPOE_SERVICE_CLASS = "com.android.server.pppoe.PppoeService"; public static void main(String[] args) { new SystemServer().run(); } private void run() { try { startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } } private void startOtherServices() { //启动网络管理服务 try { Slog.i(TAG, "NetworkManagement Service"); networkManagement = NetworkManagementService.create(context); ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement); } catch (Throwable e) { reportWtf("starting NetworkManagement Service", e); } //启动网络评分服务 try { Slog.i(TAG, "Network Score Service"); networkScore = new NetworkScoreService(context); ServiceManager.addService(Context.NETWORK_SCORE_SERVICE, networkScore); } catch (Throwable e) { reportWtf("starting Network Score Service", e); } //启动网络状态服务 try { Slog.i(TAG, "NetworkStats Service"); networkStats = new NetworkStatsService(context, networkManagement, alarm); ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats); } catch (Throwable e) { reportWtf("starting NetworkStats Service", e); } //启动网络策略服务 try { Slog.i(TAG, "NetworkPolicy Service"); networkPolicy = new NetworkPolicyManagerService( context, mActivityManagerService, (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE), networkStats, networkManagement); ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy); } catch (Throwable e) { reportWtf("starting NetworkPolicy Service", e); } //启动WIFI相关服务 mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS); mSystemServiceManager.startService(WIFI_SERVICE_CLASS); mSystemServiceManager.startService( "com.android.server.wifi.WifiScanningService"); mSystemServiceManager.startService("com.android.server.wifi.RttService"); //启动以太网服务 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) { mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS); } //启动PPPOE服务 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PPPOE)) { mSystemServiceManager.startService(PPPOE_SERVICE_CLASS); } //启动网络连接服务 try { Slog.i(TAG, "Connectivity Service"); connectivity = new ConnectivityService( context, networkManagement, networkStats, networkPolicy); ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity); networkStats.bindConnectivityManager(connectivity); networkPolicy.bindConnectivityManager(connectivity); } catch (Throwable e) { reportWtf("starting Connectivity Service", e); } //网络时间更新服务 try { Slog.i(TAG, "NetworkTimeUpdateService"); networkTimeUpdater = new NetworkTimeUpdateService(context); } catch (Throwable e) { reportWtf("starting NetworkTimeUpdate service", e); } } }

我们在这里关心其中的网络连接服务CONNECTIVITY_SERVICE和PPPOE网络服务PPPOE_SERVICE_CLASS。

frameworks/opt/net/pppoe/java/com/android/server/pppoe/PppoeService.java

public final class PppoeService extends SystemService { final PppoeServiceImpl mImpl; public PppoeService(Context context) { super(context); mImpl = new PppoeServiceImpl(context); } public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { mImpl.start(); } } }frameworks/opt/net/pppoe/java/com/android/server/pppoe/PppoeServiceImpl.java public class PppoeServiceImpl extends IPppoeManager.Stub { public PppoeServiceImpl(Context context) { mContext = context; Log.i(TAG, "Creating PppoeConfigStore"); IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); mNMService = INetworkManagementService.Stub.asInterface(b); //网络管理服务交互 mTracker = new PppoeNetworkFactory(); //重要!!!!和ConnectivityService交互 mPppoeState = "disconnect"; } public void start() { startMonitorThread(); //监听PPPOE或PPPD进程状态,与底层交互 Log.i(TAG, "Starting Pppoe service"); mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);//网络连接状态 HandlerThread handlerThread = new HandlerThread("PppoeServiceThread"); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mTracker.start(mContext, mHandler); } private void startMonitorThread() { mSocketThread = new Thread("pppoe_monitor_thread") { public void run() { LocalServerSocket server2 = new LocalServerSocket("pppoe.localsocket"); //与底层通信 /* external/ppp/pppd/utils.c void report_ppp_status(char interface[],int status){ char *name="pppoe.localsocket";//与java上层相同哦 } */ receiver2 = server2.accept(); if (receiver2 != null) { String event = br.readLine(); handleEvent(event); Log.i(TAG, "socket event = " + event); } } }; mSocketThread.start(); } private void handleEvent(String event) { setPppoeStatus(pppStatus, true); } public void setPppoeStatus(String status, boolean sendBroadcast) { sendPppBroadcast(mPppoeState); } private void sendPppBroadcast(String pppState) { Intent intent = new Intent(); intent.setAction("android.net.pppoe.PPPOE_STATE_ACTION"/*"com.mstar.android.pppoe.PPPOE_STATE_ACTION"*/); //add by tank向PppoeNetworkFactory发送广播 intent.putExtra("PppoeStatus", pppState); mContext.sendBroadcast(intent); } }frameworks/opt/net/pppoe/java/com/android/server/pppoe/PppoeNetworkFactory.java class PppoeNetworkFactory { PppoeNetworkFactory() { mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PPPOE, 0, NETWORK_TYPE, ""); mNetworkInfo.setIsAvailable(false); mLinkProperties = new LinkProperties(); initNetworkCapabilities(); mPppoeManager = null; } public synchronized void start(Context context, Handler target) { mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper()); mFactory.setCapabilityFilter(mNetworkCapabilities); mFactory.setScoreFilter(-1); // this set high when we have an iface mFactory.register(); //向ConnectivityService注册 /* frameworks/base/core/java/android/net/NetworkFactory.java public void register() { if (DBG) log("Registering NetworkFactory"); if (mMessenger == null) { mMessenger = new Messenger(this); ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG); } } frameworks/base/services/core/java/com/android/server/ConnectivityService.java public void registerNetworkFactory(Messenger messenger, String name) { NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel()); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); } private class InternalHandler extends Handler { public void handleMessage(Message msg) { case EVENT_REGISTER_NETWORK_FACTORY: { handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); break; } } } private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); mNetworkFactoryInfos.put(nfi.messenger, nfi); nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); } */ mContext = context; IntentFilter filter = new IntentFilter(); filter.addAction(PppoeManager.PPPOE_STATE_ACTION); mPppoeStateReceiver = new PppoeStateReceiver(); mContext.registerReceiver(mPppoeStateReceiver, filter); mNetworkAgent = null; updateInterfaceState(true); } }3.PPPOE网络状态监听

从上处2的源码情景分析中,我们看到pppd进程连接成功以后会通过“pppoe.localsocket”与PppoeServiceImpl通信;而PppoeServiceImpl会通过广播“android.net.pppoe.PPPOE_STATE_ACTION”通知PppoeNetworkFactory。下边直接看PppoeNetworkFactory。 frameworks/opt/net/pppoe/java/com/android/server/pppoe/PppoeNetworkFactory.java

class PppoeNetworkFactory { private class PppoeStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { checkPppoeManager(context); String action = intent.getAction(); if (action.equals(PppoeManager.PPPOE_STATE_ACTION)) { //广播 String pppState = intent.getStringExtra(PppoeManager.PPPOE_STATE_STATUE); updateInterfaceState(true); notifyStateChange(pppState); //主要是这里 } } } private void notifyStateChange(String status) { if (status.equals(PppoeManager.PPPOE_STATE_CONNECT) || status.equals(PppoeManager.PPPOE_STATE_DISCONNECT)) { if (status.equals(PppoeManager.PPPOE_STATE_CONNECT)) { updateLinkProperties(); //主要是这里 } else if (status.equals(PppoeManager.PPPOE_STATE_DISCONNECT)) { mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED,null,null); mNetworkInfo.setIsAvailable(false); } } } private void updateLinkProperties() { mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext, NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties, NETWORK_SCORE) } }frameworks/base/core/java/android/net/NetworkAgent.java public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) { ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService( Context.CONNECTIVITY_SERVICE); cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni), new LinkProperties(lp), new NetworkCapabilities(nc), score, misc); }frameworks/base/services/core/java/com/android/server/ConnectivityService.java public void registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc) { mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai)); } //消息机制不分析了,同上边registerNetworkFactory private void handleRegisterNetworkAgent(NetworkAgentInfo na) { updateNetworkInfo(na, networkInfo); } private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) { rematchNetworkAndRequests(networkAgent, false); } private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, boolean nascent) { if (currentNetwork == null || currentNetwork.getCurrentScore()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3