七、Android数据链接更新路由表

数据链接响应

sp<RILRequest> RIL::processSolicited(const Parcel& p) {
    switch (rr->mRequest) {
        case RIL_REQUEST_SETUP_DATA_CALL:
                ret =  responseSetupDataCall(p);
                break;
    }

    …....

       } else {
            if (rr->mResult != NULL) {
                AsyncResult::forMessage(rr->mResult, ret, NULL);
                rr->mResult->sendToTarget();
            }
        }
}
sp<Object> RIL::responseSetupDataCall(const Parcel & p) {
    dataCall = getDataCallResponse(p, ver);
    return dataCall;
}
sp<DataCallResponse> RIL::getDataCallResponse(const Parcel & p, int32_t version) {
      dataCall->status = p.readInt32();
            dataCall->suggestedRetryTime = p.readInt32();
            dataCall->cid = p.readInt32();
            dataCall->active = p.readInt32();
            dataCall->type = readString(p);
            dataCall->ifname = readString(p);
            sp<String> addresses = readString(p);
            sp<String> dnses = readString(p);
            sp<String> gateways = readString(p);

            return dataCall;
}
bool DataConnection::DcActivatingState::processMessage(const sp<Message>& msg) {
    switch (msg->what) {
        case EVENT_SETUP_DATA_CONNECTION_DONE: {
        DataCallResponse::SetupResult result = pDC->onSetupConnectionCompleted(ar);
            switch (result.getValue()) {
                    case DataCallResponse::SetupResult::SUCCESS: {
                    pDC->mDcFailCause = DcFailCause::NONE;
                    pDC->transitionTo(pDC->mActiveState);//状态机状态转化
                    break;
                }
        }
    }
}
DataCallResponse::SetupResult DataConnection::onSetupConnectionCompleted(const sp<AsyncResult>& ar) {
    result = updateLinkProperty(response)->setupResult;
}
sp<DataConnection::UpdateLinkPropertyResult> DataConnection::updateLinkProperty(const sp<DataCallResponse>& newState) {
    result->setupResult = setLinkProperties(newState, result->newLp);
}
void DataConnection::DcActiveState::enter() {
    pDC->notifyAllOfConnected(Phone::REASON_CONNECTED());
}
void DataConnection::notifyAllOfConnected(const android::sp<String>& reason) {
    notifyAllWithEvent(NULL, DctConstants::EVENT_DATA_SETUP_COMPLETE, reason);
}
void DcTrackerBase::handleMessage(const sp<Message>& msg) {
    switch (msg->what) {
          case DctConstants::EVENT_DATA_SETUP_COMPLETE:
        mCidActive = msg->arg1;
        onDataSetupComplete(safe_cast<AsyncResult*>(msg->obj));
        break;
    }
}
void DcTracker::onDataSetupComplete(const android::sp<AsyncResult>& ar) {
    apnContext->setState(DctConstants::State::CONNECTED);
}
void MobileDataStateReceiver::onReceive(const sp<Context>& context, const sp<Intent>& intent) {
    switch (state) {
        case PhoneConstants::DataState::CONNECTED:                  
            mdst->setDetailedState(NetworkInfo::DetailedState::CONNECTED, reason, apnName);
            break;
    }
}
void MobileDataStateTracker::setDetailedState(NetworkInfo::DetailedState state, const sp<String>& reason,const sp<String>& extraInfo) {
    sp<Message>msg=mTarget->obtainMessage(NetworkStateTracker::EVENT_STATE_CHANGED,new NetworkInfo(mNetworkInfo));
      msg->sendToTarget();
}

ConnectivityService.cpp

void ConnectivityService::MyHandler::handleMessage(const sp<Message>& msg) {
    if (msg->what == NetworkStateTracker::EVENT_STATE_CHANGED) {


        } else if (state == NetworkInfo::State::CONNECTED) { 
                             mConnectivityService->handleConnect(info); 
            } 
    }
}
void ConnectivityService::handleConnect(const sp<NetworkInfo>& info) {
    handleConnectivityChange(info, false);
}
void ConnectivityService::handleConnectivityChange(const sp<NetworkInfo>& replacedInfo, bool doReset) { 
        mNetIdtoInterfaces->put(ifa, new Integer(newNetId)); 
                mNetd->createPhysicalNetwork(newNetId); //binder到NetworkManagementService.cpp
                mNetd->addInterfaceToNetwork(ifa, newNetId);  //  1、 addInterfaceToNetwork 

        // 2、 updateRoutes
        bool resetDns = updateRoutes(newLp, curLp, (*mNetConfigs)[netType]->isDefault());
}

1、 addInterfaceToNetwork
NetworkManagementService.cpp

void NetworkManagementService::addInterfaceToNetwork(const android::sp<String> & iface, int netId) { 
    modifyInterfaceInNetwork(new String("add"), netId, iface); 
} 

void NetworkManagementService::modifyInterfaceInNetwork(const android::sp<String> & action, int netId, const android::sp<String> & iface) { 

    mConnector->doCommand(cmd, ret); 
}

NativeDaemonConnector.cpp

Vector<sp<String> > NativeDaemonConnector::doCommand(const sp<String>& cmd, int & ret) { 
    return doCommandLocked(cmd, ret); 
} 
Vector<sp<String> > NativeDaemonConnector::doCommandLocked(const sp<String>& cmd, int& ret) { 
    bool rc = sendCommandLocked(newCmd); 
}
bool NativeDaemonConnector::sendCommandLocked(const sp<String>& command) { 
    return sendCommandLocked(command, NULL); 
} 
bool NativeDaemonConnector::sendCommandLocked(const sp<String>& command, const sp<String>& argument) { 
     if (mOutputStream == NULL) { 
        return false; 
    } else { 
               mOutputStream->write(outCommand, 0, outCommand->length()); 
    } 
    return true; 
} 

socket(netd)
这个socket是在NetlinkManager中创建的
CommandListener.cpp

int CommandListener::NetworkCommand::runCommand(SocketClient* client, int argc, char** argv) { 
        if (!strcmp(argv[2], "add")) { 
            if (int ret = sNetCtrl->addInterfaceToNetwork(netId, argv[4])) { 
                return operationError(client, "addInterfaceToNetwork() failed", ret); 
            } 
        } else if (!strcmp(argv[2], "remove")) { 
            if (int ret = sNetCtrl->removeInterfaceFromNetwork(netId, argv[4])) { 
                return operationError(client, "removeInterfaceFromNetwork() failed", ret); 
            } 
        }   
}

NetworkController.cpp

int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) { 
    RouteController::addInterfaceToLocalNetworkL(netId, interface); 

    return getNetworkLocked(netId)->addInterface(interface); 
} 

PhysicalNetwork.cpp

int PhysicalNetwork::addInterface(const std::string& interface) { 
     if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(), 
                                                                 mPermission)) { 
        return ret; 
    } 
    return 0; 
} 

RouteController.cpp

int RouteController::addInterfaceToPhysicalNetwork(unsigned netId, const char* interface, 
                                                   Permission permission) { 
    if (int ret = modifyPhysicalNetwork(netId, interface, permission, ACTION_ADD)) { 
        return ret; 
    } 
    updateTableNamesFile(); 
    return 0; 
} 
WARN_UNUSED_RESULT int modifyPhysicalNetwork(unsigned netId, const char* interface, 
                                             Permission permission, bool add) { 
    uint32_t table = getRouteTableForInterface(interface); 
    if (table == RT_TABLE_UNSPEC) { 
        return -ESRCH; 
    } 

    if (int ret = modifyIncomingPacketMark(netId, interface, permission, add)) { 
        return ret; 
    } 
    if (int ret = modifyExplicitNetworkRule(netId, table, permission, INVALID_UID, INVALID_UID, add)) { 
        return ret; 
    } 
    if (int ret = modifyOutputInterfaceRule(interface, table, permission, INVALID_UID, INVALID_UID, add)) { 
        return ret; 
    } 
    return modifyImplicitNetworkRule(netId, table, permission, add); 
} 
WARN_UNUSED_RESULT int modifyExplicitNetworkRule(unsigned netId, uint32_t table, 
                                                 Permission permission, uid_t uidStart, 
                                                 uid_t uidEnd, bool add) { 

    return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_EXPLICIT_NETWORK, table, fwmark.intValue, mask.intValue, IIF_NONE, OIF_NONE, uidStart, uidEnd); 
} 
WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,uint32_t fwmark, uint32_t mask, const char* iif, const char* oif, uid_t uidStart, uid_t uidEnd) { 
    for (size_t i = 0; i < ARRAY_SIZE(AF_FAMILIES); ++i) { 
        rule.family = AF_FAMILIES[i]; 
        if (int ret = sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov))) { 
            return ret; 
        } 
    } 
}
 int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen) { 
    int sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); 
    if (sock != -1 && 
            connect(sock, reinterpret_cast<const sockaddr*>(&NETLINK_ADDRESS), 
                    sizeof(NETLINK_ADDRESS)) != -1 && 
            writev(sock, iov, iovlen) != -1 && 
            (ret = recv(sock, &response, sizeof(response), 0)) != -1) { 
        if (ret == sizeof(response)) { 
            ret = response.err.error;  // Netlink errors are negative errno. 
        }
}

2、 updateRoutes

ConnectivityService.cpp
bool ConnectivityService::updateRoutes(const sp<LinkProperties>& newLp, const sp<LinkProperties>& curLp, bool isLinkDefault) {
        if (isLinkDefault || !(r->isDefaultRoute())) { 
            addRoute(newLp, r, TO_DEFAULT_TABLE); 
        } else { 
            addRoute(newLp, r, TO_SECONDARY_TABLE); 
        } 
}
bool ConnectivityService::addRoute(const sp<LinkProperties>& p, const sp<RouteInfo>& r, 
                                   bool toDefaultTable) { 
    sp<String> pIfName = p->getInterfaceName(); 
    return  (pIfName, p, r, 0, ADD, toDefaultTable); 
} 
bool ConnectivityService::modifyRoute(const sp<String>& ifaceName, const sp<LinkProperties>& lp, const sp<RouteInfo>& r, int32_t cycleCount, bool doAdd, bool toDefaultTable) {

    if (r->getDestination() != NULL && r->getDestination()->getNetworkPrefixLength() == 32 && prefixLength != 32) { 
               sp<LinkAddress> l = new LinkAddress(r->getDestination()->getAddress(), prefixLength); 
               sp<RouteInfo> ri = new RouteInfo(l, r->getGateway()); 
               mAddedRoutes->add(ri); 
               mNetd->addRoute(ifaceName,netId, ri); 
           } else { 
               mAddedRoutes->add(r); 
               mNetd->addRoute(ifaceName,netId, r); 
           } 
}
void NetworkManagementService::addRoute(const android::sp<String> & ifname,int32_t netId, const sp<RouteInfo>& route) { 
    modifyRoute(ifname, netId, mADD, route, DEFAULT()); 
} 
void NetworkManagementService::modifyRoute(const android::sp<String> & ifname, int32_t netId, int32_t action, const sp<RouteInfo>& route, const sp<String>& type) {

    Vector<sp<String> > rsp = mConnector->doCommand(cmd->toString(), ret);
}

NativeDaemonConnector.cpp

Vector<sp<String> > NativeDaemonConnector::doCommand(const sp<String>& cmd, int & ret) { 
    return doCommandLocked(cmd, ret); 
} 
Vector<sp<String> > NativeDaemonConnector::doCommandLocked(const sp<String>& cmd, int& ret) { 
    bool rc = sendCommandLocked(newCmd); 
}
bool NativeDaemonConnector::sendCommandLocked(const sp<String>& command) { 
    return sendCommandLocked(command, NULL); 
} 
bool NativeDaemonConnector::sendCommandLocked(const sp<String>& command, const sp<String>& argument) { 
     if (mOutputStream == NULL) { 
        return false; 
    } else { 
               mOutputStream->write(outCommand, 0, outCommand->length()); 
    } 
    return true; 
} 

socket(netd)
这个socket是在NetlinkManager中创建的

CommandListener.cpp

int CommandListener::NetworkCommand::runCommand(SocketClient* client, int argc, char** argv) { 
         if (add) { 
            ret = sNetCtrl->addRoute(netId, interface, destination, nexthop, legacy, uid); 
        } else { 
            ret = sNetCtrl->removeRoute(netId, interface, destination, nexthop, legacy, uid); 
        } 
}
NetworkController.cpp
int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination, 
                                const char* nexthop, bool legacy, uid_t uid) { 
    return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid); 
} 
int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination, 
                                   const char* nexthop, bool add, bool legacy, uid_t uid) { 
            if(add) { 
     RouteController::addRoute(interface, destination, nexthop, RouteController::LOCAL_NETWORK); 
            } else { 
                RouteController::removeRoute(interface, destination, nexthop, RouteController::LOCAL_NETWORK); 
            } 
}

RouteController.cpp

int RouteController::addRoute(const char* interface, const char* destination, const char* nexthop, 
                              TableType tableType) { 
    return modifyRoute(RTM_NEWROUTE, interface, destination, nexthop, tableType); 
}
int modifyRoute(uint16_t action, const char* interface, const char* destination, const char*                nexthop, RouteController::TableType tableType) { 
    int ret = modifyIpRoute(action, table, interface, destination, nexthop); 
    return 0; 
} 
int modifyIpRoute(uint16_t action, uint32_t table, const char* interface, 
                                     const char* destination, const char* nexthop) { 
    return sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov));
}
 int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen) { 
    int sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); 
    if (sock != -1 && 
            connect(sock, reinterpret_cast<const sockaddr*>(&NETLINK_ADDRESS), 
                    sizeof(NETLINK_ADDRESS)) != -1 && 
            writev(sock, iov, iovlen) != -1 && 
            (ret = recv(sock, &response, sizeof(response), 0)) != -1) { 
        if (ret == sizeof(response)) { 
            ret = response.err.error;  // Netlink errors are negative errno. 
        }
}

注:socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); 套接字AF_NETLINK,则是用于与kernel通讯的接口。通过向量IO向kernel中发送 iov数据,并同时接收响应,错误处理。

NETD
Android5.0之后,网络的功能实现完全转移到netd上面,主要包括ip,路由配置,dns代理设置,带宽控制和流量统计等。
下面是Netd框架示意图,NetworkManagerService和NativeDeamonConnect是java代码,NetworkManagerService作为service随系统启动,java层所有对网络的操作都通过它来完成。
其他都是c++代码,主要完成两个工作:
1、接收上层的命令,完成指定对网络的操作;
2、接收kernel netlink信息,传递到上层。
接收上层命令的工作,通过4个socket完成:
/dev/socket/netd ————– CommandListener
/dev/socket/dnsproxyd ————– DnsproxyListener
/dev/socket/mdns –————– MdnsSdListener
/dev/socket/fwmarkd –————– FwmarkServer

CommandListener接收配置ip,路由,iptables的命令
DnsproxyListener接收查询dns的操作

MdnsSdListener接收针对mdnsd的操作

FwmarkServer用于对特定的socket设置mark值
这里写图片描述
下图是Netlink部分,模块调用关系示例NetlinkManager启动3个socket,用于监听3种不同的event:Uevent,RouteEvent,QuotaEvent。 通过SocketListener实现监听功能,netlink信息,最终通过/dev/socket/netd送到 NetworkManagementService(java代码),分配到注册到它里面的各个观察者实例(Ethernet,wifi等)。

这里写图片描述

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在 Android 应用内读取路由表需要使用系统权限,因此需要在 AndroidManifest.xml 文件中添加以下权限: ``` <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY"/> ``` 然后可以使用 ConnectivityManager 类的 getAllNetworks() 方法获取所有网络连接,并通过 Network 类的 getLinkProperties() 方法获取网络连接的路由表信息,示例如下: ```java ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); Network[] networks = connectivityManager.getAllNetworks(); for (Network network : networks) { LinkProperties linkProperties = connectivityManager.getLinkProperties(network); for (RouteInfo routeInfo : linkProperties.getRoutes()) { Log.d(TAG, "Route: " + routeInfo.toString()); } } ``` 需要注意的是,此方法需要 Android 6.0 及以上版本支持。 ### 回答2: 在 Android 应用内读取路由表,可以通过使用系统级别的API来实现。 首先,需要获取网络信息的权限,在 AndroidManifest.xml 文件中添加以下代码: ```xml <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> ``` 然后,在代码中使用 ConnectivityManager 类来获取网络信息,并利用 NetworkInfo 类获取路由表信息。以下是示例代码: ```java ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); if (activeNetwork != null && activeNetwork.isConnected()) { if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) { // WiFi网络 // 获取路由表信息 DhcpInfo dhcpInfo = connectivityManager.getDhcpInfo(); String gateway = Formatter.formatIpAddress(dhcpInfo.gateway); String subnetMask = Formatter.formatIpAddress(dhcpInfo.netmask); // 其他路由表信息... } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { // 移动网络 // 获取路由表信息 // ... } } ``` 上述代码首先通过 ConnectivityManager 的 getActiveNetworkInfo() 方法获取当前活动网络的信息,再通过 getType() 方法判断网络类型。如果是 WiFi 网络,则可以通过 getDhcpInfo() 方法获取路由表信息。以网关(gateway)和子网掩码(subnetMask)为例,使用 Formatter 类的 formatIpAddress() 方法将其转换为 IP 地址格式。 当然,以上示例仅仅是演示了如何在 Android 应用内读取路由表的基本步骤。根据实际需求,可能还需要处理一些网络状态的变化,或者通过其他更高级的 API 获取更详细的路由表信息。 ### 回答3: 在Android应用内读取路由表,可以使用以下方法: 1. 使用Java的NetworkInterface类获取设备的网络接口信息。通过NetworkInterface类的getNetworkInterfaces()方法可获取设备所有的网络接口,并使用NetworkInterface类提供的其他方法,如getInetAddresses()获取网络接口的IP地址等。 2. 使用Java的Process类执行shell命令,通过执行"ip route show"命令获取设备的路由表信息。可以使用ProcessBuilder类创建一个包含命令的进程,并通过Process类的getInputStream()方法获取命令执行的输入流,再通过读取输入流的方式获取命令的输出结果。 3. 使用Android的ConnectivityManager类获取设备的网络连接信息。通过ConnectivityManager类的getActiveNetworkInfo()方法获取当前活跃的网络连接对象,再使用该连接对象的getRouteInfo()方法获取网络连接的路由信息。 需要注意的是,以上方法需要在AndroidManifest.xml文件中添加相应的权限,如"android.permission.ACCESS_NETWORK_STATE"权限以获取网络连接信息。 希望以上方法能够帮助您在Android应用内读取路由表

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值