wireshark使用lua解析自定义协议

wireshark解析自定义协议

  • 1.自定义的lua放入路径
  • 2.修改init.lua
    • 2.1 开启lua
    • 2.2 init.lua文件最后加入自己的lua文件位置,这里需要确保与自己的文件名相同
  • 3.编写lua
  • 4.编写c抓包
  • 5.wireshark添加自定义协议
  • 如何加调试信息

1.自定义的lua放入路径

一般是自己软件的安装位置,也可以通过wireshark查看,这里我是直接放到init.lua同一路径就行
在这里插入图片描述

2.修改init.lua

2.1 开启lua

在这里插入图片描述

2.2 init.lua文件最后加入自己的lua文件位置,这里需要确保与自己的文件名相同

在这里插入图片描述

3.编写lua


--  这里custom_protocol 就是下一步在wireshark 新增协议的名字
-- 注册协议名称
local proto_custom = Proto("custom_protocol", "Custom Protocol")  -- 创建一个名为 "custom_protocol" 的协议,显示名称为 "Custom Protocol"

--下面的格式就是协议解析出来输出的格式,理论上前两个字段必填,base.DEC为输出的格式,DEC:十进制  HEX:十六进制 BIN:二进制
-- 定义协议字段
local f_dest_mac = ProtoField.bytes("custom_protocol.dest_mac", "Destination MAC")  -- 目标MAC地址字段
local f_src_mac = ProtoField.bytes("custom_protocol.src_mac", "Source MAC")  -- 源MAC地址字段
local f_eth_type = ProtoField.uint16("custom_protocol.eth_type", "Ethernet Type")  -- 以太网类型字段
local f_three_bit = ProtoField.uint8("custom_protocol.three_bit", "3-bit Field", base.DEC, nil, 0xE0)  -- 3位字段,位掩码为0xE0
local f_five_bit = ProtoField.uint8("custom_protocol.five_bit", "5-bit Field", base.DEC, nil, 0x1F)  -- 5位字段,位掩码为0x1F
local f_version = ProtoField.uint8("custom_protocol.version", "IP Version")  -- IP版本字段
local f_type = ProtoField.uint8("custom_protocol.type", "Type")  -- 类型字段
local f_length = ProtoField.uint16("custom_protocol.length", "Packet Length")  -- 包长度字段
local f_src_ip = ProtoField.ipv4("custom_protocol.src_ip", "Source IP")  -- 源IP地址字段
local f_dest_ip = ProtoField.ipv4("custom_protocol.dest_ip", "Destination IP")  -- 目标IP地址字段
local f_ttl = ProtoField.uint8("custom_protocol.ttl", "TTL")  -- 生存时间(TTL)字段
local f_flags = ProtoField.uint8("custom_protocol.flags", "Flags")  -- 标志字段
local f_proto_type = ProtoField.uint16("custom_protocol.proto_type", "Protocol Type")  -- 协议类型字段
local f_data_len = ProtoField.uint16("custom_protocol.data_len", "Data Length")  -- 数据长度字段
local f_data = ProtoField.string("custom_protocol.data", "Data")  -- 数据字段

-- 将字段添加到协议
proto_custom.fields = {  -- 将所有定义的字段添加到协议字段列表中
    f_dest_mac,
    f_src_mac,
    f_eth_type,
    f_three_bit,
    f_five_bit,
    f_version,
    f_type,
    f_length,
    f_src_ip,
    f_dest_ip,
    f_ttl,
    f_flags,
    f_proto_type,
    f_data_len,
    f_data
}

--buffer(offset, 1):bitfield(0, 3)  offset代表起始地址,1代表从起始地址开始的1字节  bitfield中0代表从这个字节的0bit开始, 3代表取三位(也就是取1字节的前3位)
--buffer(offset, 3):bitfield(4, 16)	这个就是取三字节中的4--20-- 解析函数
function proto_custom.dissector(buffer, pinfo, tree)
    -- 设置协议名称
    pinfo.cols.protocol = proto_custom.name  -- 将协议名称显示在协议列中

    -- 检查缓冲区长度是否足够
    local packet_len = buffer:len()
    if packet_len < 14 then  -- 如果包长度小于14字节,则退出解析
        return
    end

    -- 解析以太网头部
    local eth_dst_mac = buffer(0, 6)  -- 获取前6字节为目标MAC地址
    local eth_src_mac = buffer(6, 6)  -- 接下来的6字节为源MAC地址
    local eth_type = buffer(12, 2):uint()  -- 接下来的2字节为以太网类型

    -- 解析自定义二层字段
    local offset = 14  -- 偏移量设置为14,跳过以太网头部
    local three_bit = buffer(offset, 1):bitfield(0, 3)  -- 提取自定义字段的前3位
    local five_bit = buffer(offset, 1):bitfield(3, 5)  -- 提取剩下的5-- 解析三层协议
    offset = offset + 1  -- 更新偏移量
    local version = buffer(offset, 1):uint()  -- 读取IP版本字段
    local type = buffer(offset + 1, 1):uint()  -- 读取类型字段
    local length = buffer(offset + 2, 2):uint()  -- 读取包长度字段
    local src_ip = buffer(offset + 4, 4):ipv4()  -- 读取源IP地址字段
    local dest_ip = buffer(offset + 8, 4):ipv4()  -- 读取目标IP地址字段
    local ttl = buffer(offset + 12, 1):uint()  -- 读取TTL字段
    local flags = buffer(offset + 13, 1):uint()  -- 读取标志字段

    -- 解析四层协议
    offset = offset + 14  -- 更新偏移量
    local proto_type = buffer(offset, 2):uint()  -- 读取协议类型字段
    local data_len = buffer(offset + 2, 2):uint()  -- 读取数据长度字段
    local data = buffer(offset + 4, data_len):string()  -- 读取数据字段

    -- 在树形视图中添加协议
    local custom_tree = tree:add(proto_custom, buffer(), "USLP")  -- 添加自定义协议的根节点到树形视图
    custom_tree:add(f_dest_mac, eth_dst_mac)  -- 显示目标MAC地址
    custom_tree:add(f_src_mac, eth_src_mac)  -- 显示源MAC地址
    custom_tree:add(f_eth_type, eth_type)  -- 显示以太网类型

    -- 添加 Layer 2 协议字段
    local layer2_tree = tree:add(proto_custom, buffer(), "TFDZ")  -- 添加自定义二层协议节点到树形视图
    layer2_tree:add(f_three_bit, buffer(14, 1))  -- 显示3位字段
    layer2_tree:add(f_five_bit, buffer(14, 1))  -- 显示5位字段

    -- 添加 Layer 3 协议字段
    local layer3_tree = tree:add(proto_custom, buffer(), "EPP")  -- 添加自定义三层协议节点到树形视图
    layer3_tree:add(f_version, version)  -- 显示IP版本
    layer3_tree:add(f_type, type)  -- 显示类型字段
    layer3_tree:add(f_length, length)  -- 显示包长度
    layer3_tree:add(f_src_ip, src_ip)  -- 显示源IP地址
    layer3_tree:add(f_dest_ip, dest_ip)  -- 显示目标IP地址
    layer3_tree:add(f_ttl, ttl)  -- 显示TTL
    layer3_tree:add(f_flags, flags)  -- 显示标志

    -- 添加 Layer 4 协议字段
	-- 假如这里需要将layer4_tree 假如到layer3_tree去,而不是单独显示则
	-- local layer4_tree = layer3_tree:add(proto_custom, buffer(), "IPE")
    local layer4_tree = tree:add(proto_custom, buffer(), "IPE")  -- 添加自定义四层协议节点到树形视图
    layer4_tree:add(f_proto_type, proto_type)  -- 显示协议类型
    layer4_tree:add(f_data_len, data_len)  -- 显示数据长度
    layer4_tree:add(f_data, data)  -- 显示数据字段
end

-- 147 要与抓包是写入的值相等
-- 注册 dissector 并绑定到 DLT 147
local wtap_encap_table = DissectorTable.get("wtap_encap")  -- 获取用于注册自定义协议的封装类型表
wtap_encap_table:add(147, proto_custom)  -- 将自定义协议绑定到封装类型147,用于指定的捕获文件格式


4.编写c抓包

这里需要注意的就是147一定与lua中的值相等

#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <arpa/inet.h>

struct _timeval {
    uint32_t tv_sec;   
    uint32_t tv_usec;  
};

struct _pcap_pkthdr {
    struct _timeval ts;
    uint32_t caplen;
    uint32_t len;
};

struct pcap_global_header {
    uint32_t magic_number;
    uint16_t version_major;
    uint16_t version_minor;
    int32_t thiszone;
    uint32_t sigfigs;
    uint32_t snaplen;
    uint32_t network;
};

struct layer2_header {
    uint8_t dest_mac[6];
    uint8_t src_mac[6];
    uint16_t eth_type;
    uint8_t custom_field1:3;  // 3-bit 字段
    uint8_t custom_field2:5;  // 5-bit 字段
};

struct layer3_header {
    uint8_t version;
    uint8_t type;
    uint16_t length;
    uint32_t src_ip;
    uint32_t dest_ip;
    uint8_t ttl;
    uint8_t flags;
};

struct layer4_header {
    uint16_t proto_type;
    uint16_t data_len;
    uint8_t data[256];
};

int writePcap(int fd, char *buf, int len, struct timeval tv) {
    struct _pcap_pkthdr h;
    h.ts.tv_sec = (uint32_t)tv.tv_sec;
    h.ts.tv_usec = (uint32_t)tv.tv_usec;
    h.caplen = len;
    h.len = len;

    write(fd, &h, sizeof(h));
    write(fd, buf, len);

    return 0;
}

int writeGlobalHeader(int fd) {
    struct pcap_global_header global_header;
    global_header.magic_number = 0xa1b2c3d4;
    global_header.version_major = 2;
    global_header.version_minor = 4;
    global_header.thiszone = 0;
    global_header.sigfigs = 0;
    global_header.snaplen = 65535;
    global_header.network = 147;  // 自定义协议类型编号

    return write(fd, &global_header, sizeof(global_header)) == sizeof(global_header) ? 0 : -1;
}

int main() {
    int fd = open("./custom_protocol.pcap", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }

    if (writeGlobalHeader(fd) != 0) {
        close(fd);
        return 1;
    }

    struct layer2_header l2 = {
        .dest_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
        .src_mac = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
        .eth_type = htons(0x1234),
        .custom_field1 = 2,
        .custom_field2 = 8
    };

    struct layer3_header l3 = {
        .version = 4,
        .type = 1,
        .length = htons(20),
        .src_ip = htonl(0xC0A80001),
        .dest_ip = htonl(0xC0A80002),
        .ttl = 64,
        .flags = 2
    };

    struct layer4_header l4 = {
        .proto_type = htons(0x5678),
        .data_len = htons(5),
        .data = "hello"
    };

    uint8_t packet[1024];
    int len = 0;
    memcpy(packet, &l2, sizeof(l2));
    len += sizeof(l2);
    memcpy(packet + len, &l3, sizeof(l3));
    len += sizeof(l3);
    memcpy(packet + len, &l4, sizeof(l4));
    len += sizeof(l4);

    struct timeval tv;
    gettimeofday(&tv, NULL);

    writePcap(fd, (char*)packet, len, tv);

    close(fd);
    printf("Custom protocol pcap file generated successfully.\n");
    return 0;
}

5.wireshark添加自定义协议

在这里插入图片描述
这里header size 写0 代表从开始解析协议
在这里插入图片描述
PS:lua中不要定义名字相同的变量

如何加调试信息

直接print(“value:”, value)

需要再lua console中查看
工具 --> lua -->console
这里需要打开后双击某个具体的数据包,才会打印解析函数中的print,如果是要打印解析函数外的print,则直接cmd执行wireshark.exe

简单记录方法,方便以后回顾,具体lua语法有需要自己百度一下~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921122.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于docker进行任意项目灵活发布

引言 不管是java还是python程序等&#xff0c;使用docker发布的优势有以下几点&#xff1a; 易于维护。直接docker命令进行管理&#xff0c;如docker stop、docker start等&#xff0c;快速方便无需各种进程查询关闭。环境隔离。项目代码任何依赖或设置都可以基本独立&#x…

友思特新闻 | 友思特荣获广州科技创新创业大赛智能装备行业赛初创组优胜企业!

2024年11月19日&#xff0c;第十三届中国创新创业大赛&#xff08;广东广州赛区&#xff09;暨2024年广州科技创新创业大赛智能装备行业赛颁奖典礼隆重举行。 赛事奖项介绍&#xff1a;广州科技创新创业大赛智能装备行业赛 第十三届“中国创新创业大赛&#xff08;广东广州赛区…

FreeRTOS——消息队列

目录 一、概念及其作用 1.1概念 1.2特点 1.3工作原理 二、相关API 2.1创建队列 2.2任务中写队列 2.3任务中读队列 2.4中断中写队列 2.5中断中读队列 三、实现原理 3.1消息队列控制块 3.2消息队列的创建 3.3消息的发送 3.3.1任务中发送 3.3.2中断中发送 3.4消息的…

11 —— 打包模式的应用

需求&#xff1a;在开发模式下想让webpack使用style-loader进行css样式的处理&#xff1b;让它把css代码内嵌在js中&#xff1b;在生产模式下提取css代码 —— 判断当前运行命令时所在的环境 方案&#xff1a;借助cross-env全局软件包&#xff0c;设置参数区分打包运行环境 …

# issue 4 进程控制函数

目录 一、进程控制函数一 二、进程控制函数二 启动进程&#xff1a;&#xff08;exec系列&#xff09; 创建新进程&#xff1a; 测试代码&#xff1a; 测试结果&#xff1a; 三、进程控制函数三 结束进程&#xff1a; 测试代码&#xff1a; 测试结果&#xff1a; 四、…

C#实现blob分析——分别基于OpenCvSharp和Emgu实现

需求和效果预览 对于下图&#xff0c;需要检测左右两侧是否断开&#xff1a; 解决分析 设置左右2个ROI区域&#xff0c;找到ROI内面积最大的连通域&#xff0c;通过面积阈值和连通域宽高比判定是否断开。 可能遇到的问题&#xff1a;部分区域反光严重&#xff0c;二值化阈值不…

ZYNQ-7020嵌入式系统学习笔记(1)——使用ARM核配置UART发送Helloworld

本工程实现调用ZYNQ-7000的内部ARM处理器&#xff0c;通过UART给电脑发送字符串。 硬件&#xff1a;正点原子领航者-7020 开发平台&#xff1a;Vivado 2018、 SDK 1 Vivado部分操作 1.1 新建工程 设置工程名&#xff0c;选择芯片型号。 1.2 添加和配置PS IP 点击IP INTEGR…

冲破AI 浪潮冲击下的 迷茫与焦虑

在这个科技日新月异的时代&#xff0c;人工智能如汹涌浪潮般席卷而来&#xff0c;不断改变我们的生活。你是否对 AI 充满好奇&#xff0c;却不知它将如何改变你的工作与生活&#xff1f;又是否会在 AI 浪潮的冲击下陷入迷茫与焦虑&#xff1f;《AI 时代&#xff1a;弯道超车新思…

【FRP 内网穿透 从0到1 那些注意事项】

【摘要】 最近跟第三方团队调试问题&#xff0c;遇到一个比较烦的操作。就是&#xff0c;你必须要发个版到公网环境&#xff0c;他们才能链接到你的接口地址&#xff0c;才能进行调试。按理说&#xff0c;也没啥&#xff0c;就是费点时间。但是&#xff0c;在调试的时候&#…

基于SpringBoot+RabbitMQ完成应⽤通信

前言&#xff1a; 经过上面俩章学习&#xff0c;我们已经知道Rabbit的使用方式RabbitMQ 七种工作模式介绍_rabbitmq 工作模式-CSDN博客 RabbitMQ的工作队列在Spring Boot中实现&#xff08;详解常⽤的⼯作模式&#xff09;-CSDN博客作为⼀个消息队列,RabbitMQ也可以⽤作应⽤程…

进度条程序

目录 1.回车与换行 2.缓冲区 强制刷新&#xff1a;fflush 策略 3.倒计时程序 4.进度条 4.1先做一下基本的准备工作 4.2现在我们正式来实现 进度: 比率: 旋转光标 表明动态变化: 4.3如果我们要完成一个下载任务 4.3.1实现: 4.3.2光标显示: 4.3.2.1证明一下&#…

软件测试——自动化测试常见函数

在上一篇文章软件测试——自动化测试概念篇-CSDN博客中&#xff0c;给大家演示了一下自动化程序&#xff0c;而本篇文章会带大家详细学习selenium库。 selenium库是python官方的库&#xff0c;里面包含了很多操控浏览器的函数。 本节重点 元素定位操作测试对象窗口等待导航弹…

STM32F103C8T6实时时钟RTC

目录 前言 一、RTC基本硬件结构 二、Unix时间戳 2.1 unix时间戳定义 2.2 时间戳与日历日期时间的转换 2.3 指针函数使用注意事项 ​三、RTC和BKP硬件结构 四、驱动代码解析 前言 STM32F103C8T6外部低速时钟LSE&#xff08;一般为32.768KHz&#xff09;用的引脚是PC14和PC…

AI社媒引流工具:解锁智能化营销的新未来

在数字化浪潮的推动下&#xff0c;社交媒体成为品牌营销的主战场。然而&#xff0c;面对海量的用户数据和日益复杂的运营需求&#xff0c;传统营销方法显得力不从心。AI社媒引流王应运而生&#xff0c;帮助企业在多平台中精准触达目标用户&#xff0c;提升营销效率和效果。 1.…

知识中台:提升企业知识管理的智能化水平

在数字化转型的浪潮中&#xff0c;企业知识管理的智能化水平成为提升竞争力的关键。HelpLook知识中台通过集成先进的AI技术&#xff0c;为企业提供了一个智能化的知识管理平台。 一、知识管理智能化的重要性 智能化的知识管理不仅能够提高信息检索的效率&#xff0c;还能通过…

Unreal5从入门到精通之EnhancedInput增强输入系统详解

前言 从Unreal5开始,老版的输入系统,正式替换为EnhancedInput增强型输入系统,他们之间有什么区别呢? 如果有使用过Unity的同学,大概也知道,Unity也在2020版本之后逐渐把输入系统也升级成了新版输入系统,为什么Unreal和Unity都热衷于升级输入系统呢?这之间又有什么联系…

C语言数据结构与算法--简单实现队列的入队和出队

&#xff08;一&#xff09;队列的基本概念 和栈相反&#xff0c;队列(Queue)是一种先进先出&#xff08;First In First Out&#xff09;的线性表。只 允许在表的一端进行插入&#xff0c;而在另一端删除元素&#xff0c;如日常生活中的排队现象。队列中 允许插入的一端叫队尾…

docker搭建私有仓库,实现镜像的推送和拉取

1.拉取docker仓库镜像 docker pull registry 2.启动registry容器 docker run -d registry 3.查看当前仓库中存在的镜像&#xff08;一&#xff09; curl -XGET http://192.168.111.162: 5000/v2/_catalog 192.168.111.162 部署docker仓库宿主机的ip 5000 部署docker仓库映射到宿…

算法学习笔记(九):网格图DFS、图论算法DFS、动态规划DP、贪心

一.网格图DFS 适用于需要计算连通块个数、大小的题目 1.岛屿数量 给你一个由 1(陆地) 和 0&#xff08;水&#xff09;组成的二维网格&#xff0c;请你计算网格中岛屿的数量 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和\或竖直方向上相邻的陆地连接形成 此外&…

Cmakelist.txt之Linux-redis配置

1.cmakelist.txt cmake_minimum_required(VERSION 3.16) ​ project(redis_linux_test LANGUAGES C) ​ ​ ​ add_executable(redis_linux_test main.c) ​ # 设置hiredis库的头文件路径和库文件路径 set(Hiredis_INCLUDE_DIR /usr/local/include/hiredis) set(Hiredis_LIBRA…