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

news2024/11/18 14:01:33

背景知识

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

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

终端输入:
~ traceroute -I baidu.com
输出:
traceroute to baidu.com (39.156.66.10), 30 hops max, 60 byte packets
 1  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 ms
 3  * * *
 4  10.200.46.253 (10.200.46.253)  1.332 ms  1.333 ms  1.332 ms
 5  * * *
 6  39.156.0.85 (39.156.0.85)  4.384 ms  4.184 ms  3.936 ms
 7  111.13.188.38 (111.13.188.38)  8.991 ms  9.029 ms  9.065 ms
 8  39.156.27.1 (39.156.27.1)  4.281 ms  4.366 ms  4.377 ms
 9  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.coloradmin.cn/o/492587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【TCP为什么需要粘包和拆包】

如今&#xff0c;大半个互联网都建立在 TCP 协议之上&#xff0c;我们使用的 HTTP 协议、消息队列、存储、缓存&#xff0c;都需要用到 TCP 协议——这是因为 TCP 协议提供了可靠性。简单来说&#xff0c;可靠性就是让数据无损送达。但若是考虑到成本&#xff0c;就会变得非常复…

一文带你理解SpringBean

Bean定义 ​ Bean作为Spring框架面试中不可或缺的概念&#xff0c;其本质上是指代任何被Spring加载生成出来的对象。&#xff08;本质上区别于Java Bean&#xff0c;Java Bean是对于Java类的一种规范定义。&#xff09;Spring Bean代表着Spring中最小的执行单位&#xff0c;其…

如何用ApiFox自动生成接口文档?没有比这更详细的教程了

目录 前言 第一步&#xff1a;安装 Apifox IDEA 插件&#xff08;Apifox Helper&#xff09; 第二步&#xff1a;配置 Apifox 访问令牌 和项目 ID 第三步&#xff1a;自动生成文档&#xff01; 第四步&#xff1a;去 Apifox 项目中查看自动生成的文档 Apifox 更多好用的功能…

Addictive Multiplicative in NN

特征交叉是特征工程中的重要环节&#xff0c;在以表格型&#xff08;或结构化&#xff09;数据为输入的建模中起到了很关键的作用。 特征交互的作用&#xff0c;一是尽可能挖掘对目标有效的模式、特征&#xff0c;二是具有较好的可解释性&#xff0c;三是能够将对数据的洞见引…

一文教会你如何重装Windows10系统【过程+图解+说明】

前言 申请了一台台式机电脑&#xff0c;操作系统是windows11的&#xff0c;要windows10的系统。电脑不能连网&#xff0c;身为程序员&#xff0c;我竟然想着别人远程帮我安装&#xff0c;可恶呐。之前也没重装过系统。第一次重装遇到了一些坑。我甚至在拼夕夕上花了几块钱买个镜…

python-使用Qchart总结5-使用信号槽绘制动态曲线图

python-使用Qchart总结3-绘制曲线图在这篇文章基础上&#xff0c;来改造一下&#xff0c;绘制一下动态曲线图吧 一、明确需求 ①点击按钮&#xff0c;开始动态加载曲线&#xff0c;细节:一个一个点加载出来 二、实现 ①在UI上添加按钮&#xff0c;打开原先的untitled.ui文件…

【Linux】浅谈eloop机制

目录 1.eloop 机制 2.eloop结构体 2.1.eloop_data结构体 2.2 Socket事件结构体 2.3 Timeout事件结构体 2.4 Signal事件结构体 3.eloop_init 4.eloop_run 4.1 signal事件 4.2 socket事件 4.3 timeout事件 1.eloop 机制 主线程中启动事件监听机制&#xff0c;对不同的…

【Python入门】字符串的扩展

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于Python零基础入门系列&#xff0c;本专栏主要内容为Python基础语法、判断、循环语句、函…

Nginx介绍及安装

简介 Nginx 是一个高性能的 HTTP 和反向代理服务器。它最初由 Nigel Cook 开发&#xff0c;旨在解决 Apache 服务器在高并发环境下性能瓶颈的问题。Nginx 具有占用资源少、处理能力强等优点&#xff0c;在互联网应用中广泛应用于静态资源服务、反向代理、负载均衡、HTTP缓存、…

2023年web前端开发之JavaScript进阶(一)

接上篇博客进行学习,通俗易懂,详细 博客地址: 2023年web前端开发之JavaScript基础(五)基础完结_努力的小周同学的博客-CSDN博客 学习内容 学习 作用域、变量提升、 闭包等语言特征&#xff0c;加深对 JavaScript 的理解&#xff0c;掌握变量赋值、函数声明的简洁语法&#xff0…

rs485转tcp网关盒子怎么用(rs485协议转以太网tcp/ip)

随着工业自动化技术的不断发展&#xff0c;越来越多的工业设备在使用时需要进行数据通信。其中&#xff0c;RS485通信协议是一种常见的工业通信协议&#xff0c;而TCP/IP协议则是互联网通信的标准协议。为了实现RS485协议与TCP/IP协议之间的通信&#xff0c;可以使用RS485转TCP…

【Java】面试常问知识点(Java基础—2)

Java基础 多线程的状态 新建状态 当用new操作符创建一个线程时&#xff0c; 例如new Thread(r)&#xff0c;线程还没有开始运行&#xff0c;此时线程处在新建状态。 当一个线程处于新生状态时&#xff0c;程序还没有开始运行线程中的代码 就绪状态 一个新创建的线程并不自动…

ChatGLM-6B微调与部署

文章目录 基于ChatGLM-6B的推理与部署配置环境与准备配置环境模型文件准备 代码运行 Demo命令行 Demo基于 Gradio 的网页版 Demo基于 Streamlit 的网页版 Demo 基于peft框架的LoRA微调ChatGLM-6B配置环境与准备配置环境模型文件准备数据准备数据处理 微调过程 基于P-Tuning v2微…

stm32影子寄存器、预装载寄存器,TIM_OC1PreloadConfig和TIM_ARRPreloadConfig的作用

一直没搞清楚stm32定时器的TIM_OC1PreloadConfig、TIM_ARRPreloadConfig函数的作用&#xff0c;影子寄存器、预装载寄存器、重载寄存器的概念。今天来研究一下&#xff1a; 首先看定时器的框图&#xff1a; 图中有阴影的小方框&#xff0c;代表该功能对应的寄存器有影子寄存器&…

Canal实战使用(集群部署)和原理解析

1.mysql数据同步工作原理 MySQL master将数据变更写入二进制日志(binary log&#xff0c;其中记录叫做二进制日志事件binary log events&#xff0c;可以通过 show binlog events 进行查看) MySQL slave将master的binary log events拷贝到它的中继日志(relay log) MySQL slav…

Java基础(十八)网络编程

1. 网络编程概述 Java是 Internet 上的语言&#xff0c;它从语言级上提供了对网络应用程序的支持&#xff0c;程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库&#xff0c;可以实现无痛的网络连接&#xff0c;联网的底层细节被隐藏在 Java 的本机安装系统里&am…

软件测试培训了几个月,找到工作了,面试经验分享给各位

面试问的一些基本问题 功能方面&#xff1a;问的最多的就是测试流程&#xff0c;测试计划包含哪些内容&#xff0c;公司人员配置&#xff0c;有bug开发认为不是 bug怎么处理&#xff0c;怎样才算是好的用例&#xff0c;测试用例设计方法&#xff08;等价类&#xff0c;边界值等…

无线之红外线技术的组网方式详解

红外线(Infrared rays)也是一种光线&#xff0c;由于它的波长比红色光750nm)还长&#xff0c;超出了人眼可以识别的可见光&#xff09;范围&#xff0c;所以我们看不见它&#xff0c;又称为红外热辐射(Infrared radiation)&#xff0c;通常把波长为0.75&#xff5e;1000μm的光…

腾讯高工手写13W字“Netty速成手册”,3天走向实战

前言 在java界&#xff0c;netty无疑是开发网络应用的拿手菜。你不需要太多关注复杂的nio模型和底层网络的细节&#xff0c;使用其丰富的接口&#xff0c;可以很容易的实现复杂的通讯功能。 作为当前最流行的NIO框架&#xff0c;Netty在互联网领域、大数据分布式计算领域、游…

【Linux0.11代码分析】02 之 bootsect.s 启动流程

【Linux0.11代码分析】02 之 bootsect.s 启动流程 一、boot\bootsect.s1.1 将bootsect.s 从0x7c00 移动到 0x90000 &#xff08;512byte&#xff09;1.2 使用 int 0x13 中断加载 setup.s 程序到 0x902001.3 获取并解析磁盘驱动器的参数1.4 开始加载 System模块到 0x10000 地址1…