在Android应用中集成使用traceroute工具

news/2024/12/2 14:37:31/

背景知识

traceroute是一个常用于Linux系统的网络工具,它可显示数据包在IP网络中所经过路由的IP地址,理想状态下可探测本机和目标地址之间的所有路由节点。

其他操作系统中也有类似的替代品,实现都大同小异。一般用法如下:

终端输入:
~ traceroute -I baidu.com
输出:
traceroute to baidu.com (39.156.66.10), 30 hops max, 60 byte packets1  9.102.191.130 (9.102.191.130)  0.638 ms  0.797 ms *2  * 9.102.250.222 (9.102.250.222)  0.745 ms  0.943 ms3  * * *4  10.200.46.253 (10.200.46.253)  1.332 ms  1.333 ms  1.332 ms5  * * *6  39.156.0.85 (39.156.0.85)  4.384 ms  4.184 ms  3.936 ms7  111.13.188.38 (111.13.188.38)  8.991 ms  9.029 ms  9.065 ms8  39.156.27.1 (39.156.27.1)  4.281 ms  4.366 ms  4.377 ms9  39.156.67.1 (39.156.67.1)  3.550 ms  3.561 ms  3.568 ms
10  * * *
11  * * *
12  * * *
13  * * *
14  39.156.66.10 (39.156.66.10)  3.973 ms  3.957 ms  4.015 ms

上面例子一共有14行输出结果,我们可称之为14跳,说明数据包途径了14个节点就到达了目标机器。每一跳会发送3个数据包,所以有3个对应的时间。

具体的实现原理可以直接参考Wikipedia,主要是通过不断改变TTL值来发包实现的:

程序是利用增加存活时间(TTL)值来实现其功能的。每当数据包经过一个路由器,其存活时间就会减1。当其存活时间是0时,主机便取消数据包,并发送一个ICMP TTL数据包给原数据包的发出者。
程序发出的首3个数据包TTL值是1,之后3个是2,如此类推,它便得到一连串数据包路径。注意IP不保证每个数据包走的路径都一样。

集成到Android应用

Linux实现版本的源码在此:Traceroute for Linux,可以看到居然2023年还有一次更新。既然是Linux上的程序,有没有办法在Android上运行呢?或者直接集成到App的模块中?

因为Android系统本身没有预装traceroute命令工具(就算是在Linux上,大多发行版也是需要自己额外安装的),所以不能直接通过执行命令的方式来调用。通过NDK编译traceroute源码到App中才是比较靠谱的办法。

总的来说还是比较简单的,集成上述的Linux版本源码并添加相应的mk文件,就可以编译成库了。其实已经有开源网友实现了,GitHub上也有不少例子,这个traceroute-for-android较为完美,其中的library模块可以直接参考使用,甚至可以替换其中的traceroute源码为2023年最新版,也是没有问题的。

一些问题

为什么同一跳会出现不同的IP地址

在这里插入图片描述

在如图这个例子中,第4跳出现了一个不同的IP,很多人会比较疑惑。这是因为网络环境是不断变化的,发包过程中会选择更好的路由,可以参考这个链接中的解释:

Line 8 shows that some probes take different paths at the same step: the first and third probes go through 96.112.146.26, while the second probe goes through 96.112.146.22. This is because network conditions are constantly changing, which affects the routing tables. Here, the router 96.112.146.22 was a better choice for a brief period of time, so the previous one chose it in the second probe.

为什么要用“-I”参数

实际使用中我们会发现,很多主流的域名都无法成功trace到最终目标,最后几跳往往以星号结束,表示节点机器没有回应。这是为什么呢?

因为traceroute工具默认是发送UDP包来探测的,在当今这个复杂的互联网环境下,很多服务器都会因为安全机制拦截过滤掉UDP包,发送方得不到任何返回信息。所以在文章开头,你可以注意到我使用了“-I”参数,而不是默认无参。

在Traceroute for Linux源码文档中可以得知,此工具有多种发包方式,除了默认的UDP外,还可以用TCP、ICMP发包,后两者分别对应“-T”和“-I”参数,效果会比UDP好很多。

那么为什么我不使用更不容易被过滤的TCP发包呢?因为在非ROOT权限下,执行“-T”参数会有如下报错:

You do not have enough privileges to use this traceroute method.
socket: Operation not permitted

加sudo执行才不会报错。因为traceroute在使用TCP模式发包时会创建原始套接字,参考其源码:

static int tcp_init (const sockaddr_any *dest,unsigned int port_seq, size_t *packet_len_p) {.../*  Create raw socket for tcp   */raw_sk = socket (af, SOCK_RAW, IPPROTO_TCP);if (raw_sk < 0)error_or_perm ("socket");...
}

参考自从学会原始套接字之后,我感觉掌握了整个世界,原始套接字必须有ROOT权限才能使用:

因为网络级IP数据包没有”端口“的概念,所以可以读取网络设备传入的所有数据包,这意味着什么?意味着安全性,使用了原始套接字的应用程序可以读取所有进入系统的网络数据包,也就是我们可以捕获其他应用程序的数据包,所以为了防止这种情况的发生,Linux要求所有访问原始套接字的程序都必须以root身份运行。

我们把traceroute编译到Android的App中,运行环境就在应用层,默认是没有ROOT权限的,所以“-T”参数自然也就用不了。

低版本Android系统连“-I”也用不了

经过一些兼容性测试(覆盖了6.0及以上的所有大版本),我发现在Android 9.0及以下的系统中即便是“-I”参数也会执行失败,错误信息包含“socket bind”之类的,也就是说不同Android版本的socket函数库可能实现不同,才导致了低版本连ICMP发包都不行。

解决办法有两种:

  1. 判断Android系统版本,在9.0及以下使用默认无参的traceroute,降级到UDP发包;10.0及以后使用“-I”参数。
  2. 通过ping命令工具来模拟traceroute,因为ping工具是Android系统默认就预装了的,可以直接在Java层通过调用命令的方式执行,其次ping本身也有参数项来设置TTL值,且默认就用ICMP发包。为此我也做了一个简单的实现,可参考:TraceRouteByPing

http://www.ppmy.cn/news/59204.html

相关文章

极简爬虫通用模板

网络爬虫的一般步骤如下&#xff1a; 1、确定爬取目标&#xff1a;确定需要爬取的数据类型和来源网站。 2、制定爬取策略&#xff1a;确定爬取哪些网页、如何爬取和频率等。 3、构建爬虫程序&#xff1a;使用编程语言&#xff08;如Python&#xff09;实现爬虫程序&#xff…

Spark概述

1.Spark用来干啥的&#xff1f; Spark是一个开源的大数据处理框架&#xff0c;主要用于分布式计算和数据处理。Spark可以处理大量的数据&#xff0c;并且可以在分布式计算中进行数据处理和分析&#xff0c;具有高效性和可扩展性。Spark支持多种编程语言&#xff0c;并且可以与…

SpringCloud学习(七)——统一网关Gateway

文章目录 1. 网关介绍2. 网关搭建2.1 引入依赖2.2 创建启动类2.3 编写配置2.4 测试 3. 路由断言工厂4. 路由过滤器4.1 过滤器配置4.2 全局过滤器4.3 过滤器执行顺序 5. 跨域问题处理 1. 网关介绍 到现在&#xff0c;我们可以使用Nacos对不同的微服务进行注册并管理配置文件&am…

asp.net基于web的校园美食派送配送系统

1&#xff0e;系统登录&#xff1a;系统登录是用户访问系统的路口&#xff0c;设计了系统登录界面&#xff0c;包括用户名、密码和验证码&#xff0c;然后对登录进来的用户判断身份信息&#xff0c;判断是管理员用户还是普通用户。 2&#xff0e;系统用户管理&#xff1a;不管是…

大规模MIMO系统中基于CSI的卷积神经网络定位

来源&#xff1a;投稿 作者&#xff1a;小灰灰 编辑&#xff1a;学姐 论文标题&#xff1a;CSI-based Positioning in Massive MIMO systems using Convolutional Neural Networks 摘要 研究了使用大规模MIMO&#xff08;MaMIMO&#xff09;系统的信道状态信息&#xff08;CS…

MSQL知识学习07(MySQL执行计划分析)

1、什么是执行计划&#xff1f; 执行计划 是指一条 SQL 语句在经过 MySQL 查询优化器 的优化会后&#xff0c;具体的执行方式。 执行计划通常用于 SQL 性能分析、优化等场景。通过 EXPLAIN 的结果&#xff0c;可以了解到如数据表的查询顺序、数据查询操作的操作类型、哪些索引…

HBase(3):集群搭建

1 基础环境需求 jdk1.8以上Hadoopzookeeper 2 下载HBase安装包 Apache Downloads 3 安装 3.1 上传解压HBase安装包 tar -xvzf hbase-3.0.0-alpha-3-bin.tar.gz -C /opt/ 3.2 修改HBase配置文件 &#xff08;1&#xff09;修改hbase-env.sh cd /opt/hbase-3.0.0-alpha-3-bi…

运维简单面试题

问题&#xff1a;使用Linux命令查询file.txt中空行所在的行号 awk /^$/{print NR} file1.txt 问题&#xff1a;有文件file2.txt内容如下: 求一列的和 张三 40 李四 50 王五 60 awk {sum$2} END{print "求和"sum} file2.txt 问题&#xff1a;Shell脚本里如何检查…