当前位置: 首页 > article >正文

Wireshark 插件开发实战指南

Wireshark 插件开发实战指南

环境搭建流程图

开始
使用 TortoiseSVN 获取 Wireshark 源码
配置编译MSVC, Python 等工具链
验证依赖库与工具链完整性
环境搭建完成

一、开发环境与工具准备

(一)开发语言选择

在 Wireshark 插件开发中,选择合适的开发语言是至关重要的第一步。不同的语言有其各自的优势和适用场景。

Lua 脚本语言是一种轻量级的编程语言,它的语法简洁明了,学习曲线平缓,非常适合快速开发和原型设计。对于那些希望快速验证想法、构建简单协议解析器的开发者来说,Lua 是一个不错的选择。通过掌握 Lua 的基础语法和数据结构,开发者可以迅速上手并实现基本的功能。例如,在 Lua 中,表(table)是一种强大的数据结构,可以用来存储和操作协议中的各种字段数据。开发者可以利用 Lua 的灵活性,快速定义协议字段的结构和解析逻辑,从而在短时间内构建出一个可运行的插件原型。

然而,对于一些对性能要求较高或者需要处理复杂协议解析的场景,C 语言则更为适合。C 语言具有高效的执行速度和强大的系统级操作能力,能够直接访问内存和硬件资源。在 Wireshark 插件开发中,如果涉及到高性能的数据处理或者复杂的协议解析算法,使用 C 语言可以充分发挥其优势。不过,使用 C 语言开发需要配置较为复杂的编译环境,例如 Cygwin 或 Wireshark 源码环境。Cygwin 是一个在 Windows 系统上提供类 Unix 环境的软件,通过它可以使用 GNU 编译器工具链来编译 C 语言代码。而 Wireshark 源码环境则需要开发者具备一定的配置经验,以确保编译过程顺利进行。

(二)环境搭建

搭建一个稳定且完整的开发环境是进行 Wireshark 插件开发的基础。首先,开发者需要使用 TortoiseSVN 获取 Wireshark 源码。TortoiseSVN 是一个方便易用的 SVN 客户端,通过它可以轻松地从 Wireshark 的官方代码仓库中获取最新的源码版本。在获取源码后,需要配置编译工具链,这可能包括 MSVC(Microsoft Visual C++ Compiler)和 Python 等。MSVC 是微软提供的 C/C++ 编译器,用于编译 Windows 平台上的 C 语言代码。Python 则可能在一些脚本处理和自动化构建过程中发挥作用。配置工具链时,需要确保各个组件的版本兼容性,避免因版本不匹配导致的编译错误。

同时,验证依赖库与工具链的完整性也是环境搭建过程中不可忽视的一步。Wireshark 插件开发可能会依赖一些第三方库,如 Qt 库用于图形界面相关的功能。开发者需要逐一检查这些依赖库是否正确安装,并且与工具链协同工作。例如,在编译过程中,如果缺少某个依赖库,可能会出现链接错误,导致编译失败。因此,通过仔细的验证,确保所有依赖库和工具链都完整无误,可以为后续的开发工作提供一个良好的基础。

(三)开发者工具推荐

在开发过程中,合适的工具能够大大提高开发效率和调试的便捷性。Wireshark 自带的内置调试器(Protocol Dissection Debugger)是一个非常有用的工具。它可以帮助开发者在调试协议解析器时设置断点,逐步执行代码,观察程序的运行状态和变量的值。通过这种方式,开发者可以深入了解协议解析的每一个细节,及时发现和修复潜在的问题。例如,在解析一个复杂的协议数据包时,通过在关键的解析函数处设置断点,可以检查数据包的各个字段是否被正确解析和处理。

此外,日志输出也是一个常用的调试手段。在代码中插入 print() 函数,可以将关键变量的值和程序的运行状态输出到控制台。这对于定位问题非常有帮助,尤其是在程序运行出现异常或者结果不符合预期时。通过查看日志输出,开发者可以快速定位到问题发生的代码位置,从而有针对性地进行修复。

二、核心开发技巧

(一)熟悉 Wireshark API

Wireshark 提供了一系列丰富的 API,供开发者在插件开发中使用。其中,Dissector 对象是协议解析的核心部分。它定义了协议解析的逻辑,包括如何处理数据包的结构和字段解析。开发者需要通过 Wireshark 的 API 来创建和操作 Dissector 对象,以实现对特定协议的解析。例如,在解析一个自定义协议时,可以通过 Dissector 对象来指定如何从数据包中提取协议的各个字段,并将其显示在 Wireshark 的协议树中。

ProtoField 类则是用于描述协议字段的显示名称、数据类型及过滤规则的重要工具。通过定义 ProtoField,开发者可以告诉 Wireshark 如何显示协议字段,以及如何在过滤器中使用这些字段。例如,如果一个协议字段是一个 16 位无符号整数,开发者可以使用 FT_UINT16 来定义其数据类型。同时,还可以为该字段设置一个显示名称,方便用户在 Wireshark 界面中识别和使用。

协议解析器开发流程图

注册协议与字段
使用 `proto_register_protocol`
使用 `proto_register_field_array`
数据包处理函数
解析 `tvbuff_t` 缓冲区
构建协议树

(二)协议解析器(Dissector)开发

开发一个协议解析器是 Wireshark 插件开发的核心任务之一。首先,需要通过 proto_register_protocol 函数注册协议。在这个函数中,开发者需要指定协议的名称、描述和缩写等信息。这些信息将在 Wireshark 界面中显示,帮助用户识别和选择该协议。接着,使用 proto_register_field_array 函数注册协议的字段。在这个函数中,需要传入之前定义的 ProtoField 数组,以便 Wireshark 知道该协议有哪些字段以及它们的属性。

然后,需要实现数据包处理函数,通常命名为 dissect_myprotocol。在这个函数中,开发者需要解析 tvbuff_t 缓冲区的内容。tvbuff_t 是 Wireshark 中用于表示数据包缓冲区的结构,它包含了数据包的数据和一些相关的元信息。开发者可以通过 Wireshark 的 API 从 tvbuff_t 缓冲区中提取数据,并根据协议的定义进行解析。解析完成后,需要构建协议树,将解析出的字段按照一定的结构显示在 Wireshark 的协议树中。例如,可以使用 proto_tree_add_uint 函数将一个整数字段添加到协议树中。

(三)插件入口与注册

为了让 Wireshark 能够识别和加载开发的插件,需要定义插件入口和注册函数。plugin_register 函数是插件的入口函数,在这个函数中,开发者可以进行一些插件的初始化工作,如注册协议解析器等。而 plugin_reg_handoff 函数则用于完成协议解析器的动态加载与注册。通过在这个函数中调用相关的注册函数,可以将开发的协议解析器与 Wireshark 的解析流程结合起来,使得 Wireshark 能够在解析数据包时调用插件中的解析器。

三、调试与测试技巧

(一)调试方法

在开发过程中,调试是必不可少的环节。利用 Wireshark 的内置调试器,开发者可以方便地设置断点,逐步检查数据包解析逻辑。例如,在解析一个复杂的数据包时,可以在解析函数的关键位置设置断点,然后通过调试器逐步执行代码,观察程序的运行状态和变量的值。这样可以及时发现解析过程中出现的问题,如数据提取错误、字段解析不正确等。

同时,通过控制台日志输出关键变量值也是一种有效的调试方法。在代码中插入日志输出语句,可以将程序运行过程中的关键信息输出到控制台。例如,在解析一个字段后,可以通过日志输出该字段的值,以便检查其是否符合预期。通过结合使用内置调试器和日志输出,开发者可以更全面地了解程序的运行情况,快速定位和解决问题。

测试策略流程图

多样化测试环境
覆盖不同网络条件
覆盖不同数据包类型
自动化测试脚本
验证插件功能
提升迭代效率

(二)测试策略

为了确保开发的插件能够稳定可靠地运行,制定合理的测试策略非常重要。首先,需要在多样化的测试环境中进行测试。不同的网络条件和数据包类型可能会对插件的性能和功能产生不同的影响。例如,在测试一个支持多种网络协议的插件时,需要在不同的网络拓扑结构、不同的网络延迟和丢包率等条件下进行测试,以确保插件在各种环境下都能正常工作。同时,还需要测试各种类型的数据包,包括正常数据包、异常数据包、分片数据包、加密流量等,以验证插件对不同数据包的处理能力。

其次,编写自动化测试脚本可以提高测试的效率和覆盖率。通过使用自动化测试工具,如 Python 的 unittest 框架,开发者可以编写测试脚本来模拟各种测试场景,自动运行测试并生成测试报告。这样可以节省大量的手动测试时间,同时确保测试的全面性和一致性。例如,可以编写一个测试脚本,自动发送各种类型的数据包到 Wireshark,并检查插件的解析结果是否正确。

四、性能优化与维护

(一)性能提升

在 Wireshark 插件开发中,性能是一个重要的考虑因素。为了提高插件的性能,可以采取一些优化措施。首先,减少内存分配与重复计算是提高性能的有效方法。频繁的内存分配和重复计算会消耗大量的系统资源,降低程序的运行速度。通过使用缓存技术,可以将一些常用的计算结果或数据存储起来,避免重复计算和分配。例如,在解析一个频繁出现的协议字段时,可以将其解析结果缓存起来,下次遇到相同的数据时直接从缓存中获取,而不需要重新计算。

其次,避免过度解析也是提高性能的一个重要方面。在解析数据包时,只处理必要的字段,避免对无关的数据进行解析。这样可以减少程序的运行时间,降低资源消耗。例如,在解析一个大型数据包时,如果只需要其中的几个关键字段,可以只解析这些字段,而跳过其他无关的部分。

(二)代码维护与扩展

随着时间和需求的变化,插件的代码需要不断地进行维护和扩展。良好的文档化是代码维护和扩展的基础。通过详细记录协议解析逻辑与接口设计,开发者可以方便地理解代码的功能和结构,为后续的维护和扩展提供指导。例如,在代码中添加详细的注释,说明每个函数的作用、参数和返回值,以及协议解析的流程和关键点,可以帮助其他开发者快速上手。

同时,定期更新插件以兼容新版 Wireshark 及协议规范变更也是维护工作的重要部分。Wireshark 和各种网络协议都在不断发展和更新,插件需要及时跟进这些变化,以确保其能够正常运行并满足用户的需求。例如,当 Wireshark 发布新版本时,需要检查插件是否与新版本兼容,如有必要,进行相应的修改和测试。

五、参考资源与社区支持

(一)官方示例与源码

Wireshark 官方提供了许多示例和源码,这些资源对于开发者来说是非常宝贵的。通过参考 Wireshark 内置插件的实现,如 plugins/m2m 的 WiMax 协议实现,开发者可以学习到许多实用的开发技巧和最佳实践。这些示例通常包含了完整的插件开发流程,从协议解析器的开发到插件的注册和加载,开发者可以从中了解到如何组织代码、如何使用 Wireshark 的 API 等。

参考资源流程图

graph TDA[官方示例与源码] --> B[参考 Wireshark 内置插件]C[社区与文档] --> D[加入 Wireshark 开发者论坛]C --> E[查阅开发者指南 (WSDG)]

(二)社区与文档

Wireshark 的开发者社区是一个活跃的交流平台,开发者可以在这里找到许多有用的信息和帮助。通过加入 Wireshark 开发者论坛,开发者可以与其他开发者交流经验,学习到许多解决问题的方法和技巧。同时,社区中还经常分享一些实际的开发案例和解决方案,这些都可以为开发者提供参考和借鉴。

此外,查阅开发者指南(WSDG)与 API 文档也是获取知识的重要途径。开发者指南详细介绍了 Wireshark 插件开发的各个方面,包括开发环境的搭建、API 的使用、插件的调试和测试等。API 文档则提供了 Wireshark 各个 API 的详细说明和使用示例,开发者可以通过查阅这些文档,深入了解 Wireshark 的功能和使用方法。

六、常见问题与解决方案

(一)协议分片与重组流程图

参考 TCP/UDP 示例
处理分片数据包
重组分片数据

(一)协议分片与重组

在协议解析过程中,经常会遇到数据包分片的情况。当一个数据包被分片后,需要将各个分片重新组合起来,才能正确解析出完整的协议数据。对于这种情况,可以参考 TCP/UDP 协议的分片处理示例。TCP 和 UDP 协议都支持数据包的分片传输,在 Wireshark 中,它们的解析器能够正确处理分片数据包的重组。开发者可以借鉴这些示例,实现自己协议的分片处理逻辑。例如,可以通过记录各个分片的信息,如序列号、长度等,然后根据这些信息将分片组合起来,形成完整的数据包。

隧道协议解析流程图

结合现有VPN 协议等插件
实现多层协议嵌套解析
解析外层协议
解析内层协议

(二)隧道协议解析

隧道协议是一种将一种协议封装在另一种协议中的技术,在网络通信中广泛应用。对于隧道协议的解析,需要结合现有插件的实现。例如,在解析 VPN 协议时,可以参考相关的 VPN 插件,了解如何处理多层协议嵌套的情况。通常,隧道协议的解析需要先解析外层协议,然后根据外层协议中的信息,找到内层协议的数据部分,再对内层协议进行解析。通过这种方式,可以逐步解开隧道协议的嵌套结构,正确解析出各个协议层的数据。

相关文章:

Wireshark 插件开发实战指南

Wireshark 插件开发实战指南 环境搭建流程图 #mermaid-svg-XpNibno7BIyfzNn5 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XpNibno7BIyfzNn5 .error-icon{fill:#552222;}#mermaid-svg-XpNibno7BIyfzNn5 .error-t…...

使用Java构建高效的Web服务架构

使用Java构建高效的Web服务架构 随着互联网技术的飞速发展,Web服务在现代应用中扮演着至关重要的角色。尤其是在企业级应用中,如何构建一个高效、可扩展且易维护的Web服务架构,成为了开发者和架构师面临的一项重要挑战。Java作为一种成熟、稳…...

《Python实战进阶》No 10:基于Flask案例的Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻击

第10集:Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻击 在现代 Web 开发中,安全性是至关重要的。无论是用户数据的保护,还是系统稳定性的维护,开发者都需要对常见的 Web 安全威胁有深刻的理解,并采取有效的防…...

蓝桥备赛(六)- C/C++输入输出

一、OJ题目输入情况汇总 OJ(online judge) 接下来会有例题 , 根据一下题目 , 对这些情况进行分析 1.1 单组测试用例 单在 --> 程序运行一次 , 就处理一组 练习一:计算 (ab)/c 的值 B2009 计算 (ab)/c …...

企微审批中MySQL字段TEXT类型被截断的排查与修复实践

在MySQL中,TEXT类型字段常用于存储较大的文本数据,但在一些应用场景中,当文本内容较大时,TEXT类型字段可能无法满足需求,导致数据截断或插入失败。为了避免这种问题,了解不同文本类型(如TEXT、M…...

[ISP] AE 自动曝光

相机通过不同曝光参数(档位快门时间 x 感光度 x 光圈大小)控制进光量来完成恰当的曝光。 自动曝光流程大概分为三部分: 1. 测光:点测光、中心测光、全局测光等;通过调整曝光档位使sensor曝光在合理的阈值内&#xff0…...

小程序画带圆角的圆形进度条

老的API <canvas id"{{canvasId}}" canvas-id"{{canvasId}}" style"opacity: 0;" class"canvas"/> startDraw() {const { canvasId } this.dataconst query this.createSelectorQuery()query.select(#${canvasId}).bounding…...

16. LangChain实战项目2——易速鲜花内部问答系统

需求简介 易束鲜花企业内部知识库如下&#xff1a; 本实战项目设计一个内部问答系统&#xff0c;基于这些内部知识&#xff0c;回答内部员工的提问。 在前面课程的基础上&#xff0c;需要安装的依赖包如下&#xff1a; pip install docx2txt pip install qdrant-client pip i…...

代码的解读——自用

代码来自&#xff1a;https://github.com/ChuHan89/WSSS-Tissue?tabreadme-ov-file 借助了一些人工智能 run_pipeline.sh 功能总结 该脚本用于执行一个 弱监督语义分割&#xff08;WSSS&#xff09; 的完整流程&#xff0c;包含三个阶段&#xff1a; Stage1&#xff1a;训…...

蓝桥杯试题:DFS回溯

一、题目要求 输入一个数组n&#xff0c;输出1到n的全排列 二、代码展示 import java.util.*;public class ikun {static List<List<Integer>> list new ArrayList<>();public static void main(String[] args) { Scanner sc new Scanner(System.in);…...

FPGA开发,使用Deepseek V3还是R1(8):FPGA的全流程(简略版)

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…...

一个py文件搞定mysql查询+Json转换+表数据提取+根据数据条件生成excel文件+打包运行一条龙

import os import argparse import pymssql import json import pandas as pd from datetime import datetime from pandas.io.formats.excel import ExcelFormatter import openpyxl# 投注类型映射字典 BET_MAPPING {1: WIN, 2: PLA, 3: QIN, 4: QPL,5: DBL, 6: TCE, 7: QTT,…...

微服务学习(1):RabbitMQ的安装与简单应用

目录 RabbitMQ是什么 为什么要使用RabbitMQ RabbitMQ的安装 RabbitMQ架构及其对应概念 队列的主要作用 交换机的主要作用 RabbitMQ的应用 通过控制面板操作&#xff08;实现收发消息&#xff09; RabbitMQ是什么 RabbitMQ是一个开源的消息队列软件&#xff08;消息代理…...

【RAG】Embeding 和 Rerank学习笔记

Q: 现在主流Embeding模型架构 在RAG&#xff08;Retrieval-Augmented Generation&#xff09;系统中&#xff0c;嵌入模型&#xff08;Embedding Model&#xff09; 是检索阶段的核心组件&#xff0c;负责将查询&#xff08;Query&#xff09;和文档&#xff08;Document&#…...

【Delphi】如何解决使用webView2时主界面置顶,而导致网页选择文件对话框被覆盖问题

一、问题描述&#xff1a; 在Delphi 中使用WebView2控件&#xff0c;如果预先把主界面置顶&#xff08;Self.FormStyle : fsStayOnTop;&#xff09;&#xff0c;此时&#xff0c;如果在Web页面中有使用&#xff08;<input type"file" id"fileInput" acc…...

【量化金融自学笔记】--开篇.基本术语及学习路径建议

在当今这个信息爆炸的时代&#xff0c;金融领域正经历着一场前所未有的变革。传统的金融分析方法逐渐被更加科学、精准的量化技术所取代。量化金融&#xff0c;这个曾经高不可攀的领域&#xff0c;如今正逐渐走进大众的视野。它将数学、统计学、计算机科学与金融学深度融合&…...

iOS 使用消息转发机制实现多代理功能

在iOS开发中&#xff0c;我们有时候会用到多代理功能&#xff0c;比如我们列表的埋点事件&#xff0c;需要我们在列表的某个特定的时机进行埋点上报&#xff0c;我们当然可以用最常见的做法&#xff0c;就是设置代理实现代理方法&#xff0c;然后在对应的代理方法里面进行上报&…...

16.3 LangChain Runnable 协议精要:构建高效大模型应用的核心基石

LangChain Runnable 协议精要:构建高效大模型应用的核心基石 关键词:LCEL Runnable 协议、LangChain 链式开发、自定义组件集成、流式处理优化、生产级应用设计 1. Runnable 协议设计哲学与核心接口 1.1 协议定义与类结构 #mermaid-svg-PlmvpSDrEUrUGv2p {font-family:&quo…...

Starrocks入门(二)

1、背景&#xff1a;考虑到Starrocks入门这篇文章&#xff0c;安装的是3.0.1版本的SR&#xff0c;参考&#xff1a;Starrocks入门-CSDN博客 但是官网的文档&#xff0c;没有对应3.0.x版本的资料&#xff0c;却有3.2或者3.3或者3.4或者3.1或者2.5版本的资料&#xff0c;不要用较…...

【北京迅为】itop-3568 开发板openharmony鸿蒙烧写及测试-第1章 体验OpenHarmony—烧写镜像

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…...

Electron一小时快速上手

1. 什么是 Electron? Electron 是一个跨平台桌面应用开发框架&#xff0c;开发者可以使用 HTML、CSS、JavaScript 等 Web 技术来构建桌面应用程序。它的本质是结合了 Chromium 和 Node.js&#xff0c;现在广泛用于桌面应用程序开发。例如&#xff0c;以下桌面应用都使用了 El…...

算法004——盛最多水的容器

力扣——盛最多水的容器点击即可跳转 当我们选择1号线和8号线时&#xff0c;下标为 1 和 8 形成容器的容积的高度是由 较矮的决定的&#xff0c;即下标为 8 的位置&#xff1b; 而宽度则是 1到8 之间的距离&#xff0c;为 8-17&#xff0c;此时容器的容积为 7 * 7 49。 当我…...

Java Web-Filter

Filter 在 Java Web 开发中&#xff0c;Filter&#xff08;过滤器&#xff09;是 Servlet 规范中的一个重要组件&#xff0c;它可以对客户端与服务器之间的请求和响应进行预处理和后处理。以下从多个方面详细介绍 Java Web 中的 Filter&#xff1a; 一、概念和作用 概念&…...

LeetCode 热题100 438. 找到字符串中所有字母异位词

LeetCode 热题100 | 438. 找到字符串中所有字母异位词 大家好&#xff0c;今天我们来解决一道经典的算法题——找到字符串中所有字母异位词。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求我们在字符串 s 中找到所有是 p 的异位词的子串&#xff0c;并返回这些子串的…...

DeepSeek-R1训练时采用的GRPO算法数学原理及算法过程浅析

先来简单看下PPO和GRPO的区别&#xff1a; PPO&#xff1a;通过奖励和一个“评判者”模型&#xff08;critic 模型&#xff09;评估每个行为的“好坏”&#xff08;价值&#xff09;&#xff0c;然后小步调整策略&#xff0c;确保改进稳定。 GRPO&#xff1a;通过让模型自己生…...

Qt基于信号量QSemaphore实现的生产者消费者模型

在 Qt 中&#xff0c;信号量&#xff08;QSemaphore&#xff09;是一种用于控制对共享资源访问的同步工具。它允许一定数量的线程同时访问共享资源&#xff0c;适合用于生产者-消费者模型。 代码实现 #include <QCoreApplication> #include <QThread> #include &…...

七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)

七星棋牌源码 是一款运营级的棋牌产品&#xff0c;覆盖 湖南、湖北、山西、江苏、贵州 等 6 大省区&#xff0c;支持 安卓、iOS 双端&#xff0c;并且 全开源。这个版本是 修复优化后的二开版本&#xff0c;新增了 乐豆系统、比赛场模式、防沉迷机制、AI 智能控制 等功能&#…...

CSDN博客导出设置介绍

在CSDN编辑博客时&#xff0c;如果想导出保存到本地&#xff0c;可以选择导出为Markdown或者HTML格式。其中导出为HTML时有这几种选项&#xff1a;jekyll site&#xff0c;plain html&#xff0c;plain text&#xff0c;styled html&#xff0c;styled html with toc。分别是什…...

_ 为什么在python中可以当变量名

在 Python 中&#xff0c;_&#xff08;下划线&#xff09;是一个有效的变量名&#xff0c;这主要源于 Python 的命名规则和一些特殊的使用场景。以下是为什么 _ 可以作为变量名的原因和常见用途&#xff1a; --- ### 1. **Python 的命名规则** Python 允许使用字母&#xff…...

使用haproxy实现MySQL服务器负载均衡

一、环境准备 主机名IP地址备注openEuler-1192.168.121.11mysql-server-1openEuler-2192.168.121.12mysql-server-2openEuler-3192.168.121.13clientRocky-1192.168.121.51haproxy 二、mysql-server配置 [rootopenEuler-1 ~]# yum install -y mariadb-server [rootopenEuler…...