ndpi工作流程

article/2025/10/30 8:16:11

这里以ndpi的例程ndpiReader.c为例,讲述一下ndpi从抓包到最终分析出具体协议的流程。简单来讲ndpi是从下层开始逐层向上对数据包进行分析的。
先上一发自己画的流程图
这张图是我在最开始看ndpi源码的时候做的流程图,还不是非常的清楚和正确,就连函数的调用关系也只是按先后顺序画的,现在看起来真是有点low,不过也大致说明了一些问题,也就懒得修改了。我会在接下来的文章中说明。这里如果大家想真正了解其工作流程的话,最好自己通过gdb工具进行调试,进入example文件夹,运行gdb -tui ndpiReader命令,在test文件夹下找到.pcap文件或者自己上网抓个包都行,然后在gdb命令行中设置断点,运行 r -i *.pcap即可进入调试模式~~可以百度一下gdb调试相关知识。
NDPI工作流程

第一步是程序的初始化,调用setupDetection()函数,这里所做的工作也比较多,打算新写一篇文章来专门讲述此函数作用。
接下来会开启线程调用libpcap库函数对通过电脑网卡的数据包进行抓取,或者读取传入的.pcap文件(具体的 如何运行等简单操作可以参考官方给出的文档,在doc文件夹下)
接下来对每一个数据包(这里需要明确两个概念,数据包(packet)和数据流(flow),一个数据流中可能会有很多个数据包,就像我们申请一个网页请求,由于页面信息很大,所以会分成很多个数据包来传输,但这些数据包同属于一个数据流),首先对其数据链路层和IP层进行拆包分析pcap_packet_callback()函数,判断是否为基于IP协议等,并获得其源目的IP、协议类型等。
在接下来调用packet_processing()函数,进行传输层分析。在进行传输层分析时调用了get_ndpi_flow()函数,该函数返回ndpi_flow这个结构体(这里需要注意ndpi_flow和ndpi_flow_struct两个结构体的区别)。在get_ndpi_flow()函数中获取传输层的信息如源目的端口等信息。然后根据(源目的IP、源目的端口、协议类型(tcp\udp))这五个元素计算出idx。

idx = (vlan_id + lower_ip + upper_ip + iph->protocol + lower_port + upper_port) % NUM_ROOTS;ret = ndpi_tfind(&flow, &ndpi_thread_info[thread_id].ndpi_flows_root[idx], node_cmp);

这里就是我刚开始开源码时困扰我的地方,开始一直不知道idx的作用,后来发现程序维护了一个数组,用来记录所有的数据流,而idx是用来标识不同的数据流,根据前面解析出数据包的五元组计算idx,然后查询 ndpi_flows_root[]这个数组在索引为idx位置是否已经有了记录。一般,对于一个数据流而言,该流的第一个数据包查询时ndpi_flows_root[idx]为空,则建立一个新的ndpi_flow对象并保存到该位置处;等抓到该数据流的后续数据包时,因为属于同一个流(即idx相同),所以ndpi_flows_root[idx]不为空,则直接返回已经有的ndpi_flow即可。至此,我们得到了ndpi_flow这个结构体,这也是get_ndpi_flow()这个函数的意义。

接下来函数会调用ndpi_detection_process_packet()这个函数进行应用层分析。这也是应用协议分析的主体函数。注意这个函数传进的参数是ndpi_flow_struct(下面记为flow),函数首先会对flow->packet即对packet这个结构体进行初始化。因为对于同一个流flow而言,在该结构体中有些变量在第一个数据包时已经初始化了,这些变量可能在特定情况下才会发生改变,比如检测出了协议等;而对每一个数据包,flow中必须要变的就是flow->packet中的信息。接下来会调用ndpi_connection_tracking()函数,这个函数的主要作用是判断这个包的‘位置’,熟悉tcp协议的人都知道,一个tcp经过三次握手建立连接bababababa….这里自行脑补,主要要知道syn,ack,seq,ack_seq四个变量的作用和功能。这个函数在数据包重组等功能中会有很重要的作用。这里贴出部分代码

    if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0&& flow->l4.tcp.seen_ack == 0) {flow->l4.tcp.seen_syn = 1;}//第一次if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0&& flow->l4.tcp.seen_ack == 0) {flow->l4.tcp.seen_syn_ack = 1;}//第二次if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1&& flow->l4.tcp.seen_ack == 0) {flow->l4.tcp.seen_ack = 1;}//第三次//上面三句是三次握手相应的判断语句if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0)|| (proxy_enabled && (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0))) {if(tcph->ack != 0) {//packet_direction表示方向是从源IP到目的IP\从目的IP到源IPflow->next_tcp_seq_nr[flow->packet.packet_direction] =ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);if(!proxy_enabled) {flow->next_tcp_seq_nr[1 -flow->packet.packet_direction] = ntohl(tcph->ack_seq);}}} else if(packet->payload_packet_len > 0) {/* check tcp sequence counters */if(((u_int32_t)(ntohl(tcph->seq) -flow->next_tcp_seq_nr[packet->packet_direction])) >ndpi_struct->tcp_max_retransmission_window_size) {packet->tcp_retransmission = 1;}

接下来会对ndpi_selection_packet进行设置,这个变量主要记录每个数据包的下四层信息。该变量是NDPI_SELECTION_BITMASK_PROTOCOL_SIZE类型,大概就是一个10101011这样的东西,如下面代码所示,把这几个变量进行与或操作得到一个值,比如110111101中的两个0就表示不是IPV6和不是TCP。

#define NDPI_SELECTION_BITMASK_PROTOCOL_SIZE            u_int32_t
#define NDPI_SELECTION_BITMASK_PROTOCOL_IP          (1<<0)
#define NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP         (1<<1)
#define NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP         (1<<2)//移位操作
#define NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP      (1<<3)
#define NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD     (1<<4)
#define NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION   (1<<5)
#define NDPI_SELECTION_BITMASK_PROTOCOL_IPV6            (1<<6)
#define NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6        (1<<7)
#define NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC    (1<<8)

在接下来调用下面代码,这里的guessed_protocol_id 我还没有搞明白是做什么用的,之后用到再看吧

flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol,sport, dport);flow->protocol_id_already_guessed = 1;

最后,调用check_ndpi_flow_func()函数进行具体应用协议的检测,这里会根据tcp\udp\二者都不进入不同的接口。这里的东西也比较多,暂时想着针对http协议类型再写一篇文章,所以就不详细叙述了。经过这个函数之后如果仍然没有检测出协议类型,那么就继续检测下一个数据包直到检测出该数据流的协议类型为止。


http://chatgpt.dhexx.cn/article/MQDSMukT.shtml

相关文章

【随笔记】linux usb gadget ncm wrong ndp sign 问题修复

一、模拟网卡简介 在 Linux 通过 usb 模拟网卡时&#xff0c;有四种方式&#xff1a; 1. 使用 usb gadget rndis 2. 使用 usb gadget ecm 3. 使用 usb gadget ncm 4. 使用 usb gadget eem rndis&#xff1a;是微软公司制定的协议规范, 不过似乎规范不完整, 引起 rndis host …

nDPI分析

nDPI分析 一.概述 nDPI是保持高度欢迎的OpenDPI&#xff0c;在GPL证书下发布&#xff0c;它的目标是增加新的协议&#xff0c;扩展原有的库&#xff1b;为了支持多平台的体验&#xff0c;它除了支持UNIX系列外&#xff0c;还支持windows版本&#xff1b;而且&#xff0c;可以…

如何实现在on ethernetPacket中自动回复NDP response消息

对于IPv4协议来说,如果主机想通过目标ipv4地址发送以太网数据帧给目的主机,需要在数据链路层填充目的mac地址。根据目标ipv4地址查找目标mac地址,这是ARP协议的工作原理 对于IPv6协议来说,根据目标ipv6地址查找目标mac地址,它使用的不是ARP协议,而是邻居发现NDP(Neighb…

IPv6 NDP邻居发现协议 1

NDP&#xff08;Neighbor Discovery Protocol&#xff0c;邻居发现协议&#xff09;是IPv6的一个关键协议&#xff0c;它组合了IPv4中的ARP、ICMP路由器发现和ICMP重定向等协议&#xff0c;并对它们作了改进。作为IPv6的基础性协议&#xff0c;NDP还提供了前缀发现、邻居不可达…

NPDP是什么?

NPDP由美国产品开发与管理协会&#xff08;PDMA&#xff09;发起&#xff0c;是国际公认的唯一的新产品开发专业认证&#xff0c;集理论、方法与实践为一体的全方位知识体系。 一&#xff0c;为什么要考NPDP认证&#xff1f; 1.对于个人&#xff1a; 1&#xff09;确保精通新…

802.11 NDP Sounding

NDP Sounding 1.NDP原理2.NDP 过程3.帧结构3.1 NDPA结构3.2 CBF帧 1.NDP原理 802.11n标准提供的波束成形技术&#xff0c;可以通过预先补偿发射天线的相位&#xff0c;让两条波束进行叠加以实现最好的效果 显式波束成形需要终端反馈信道信息&#xff1a; AP向STA发送探测数据…

【IPv6】IPv6 NDP邻居状态详解

NDP 邻居状态 任意两个通信的主机在通信之前&#xff0c;先要建立邻居。&#xff08;省的去查找arp了&#xff09; 因为接下来的文字会很乱&#xff0c;排版费劲&#xff0c;所以用这个来。 未完成(Incomplete),可达(Reachable),陈旧(Stale),延迟(Delay),探查(Probe) 正常过程…

ICMPV6协议及NDP协议

一、ICMPV6 1、基于ipv6的ICMPv6&#xff08;Internet control message protocol for IPv6&#xff09;是 IPv6 下的 Internet 控制报文协议&#xff1b;在 IPv6 中&#xff0c;ICMPv6 整合实现了 IPv4 中的 ICMP&#xff08;ping命令&#xff09;、ARP 以及 IGMP 的所有功能&a…

IPV6 邻居发现协议(NDP)

IPV6除了显著增加了地址空间外&#xff0c;另一个最显著的特征就是它的即插即用性。 邻居发现协议(Neighbor Discovery Protocol&#xff0c;NDP)就是使用以下的功能实现即插即用特性的协议&#xff1a; 路由器发现&#xff1a;当一个节点连接到一个IPV6的链路时&#xff0c;它…

802.11 - NDP反馈报告

目录 概述 帧格式 能力指示 NFRP Trigger帧格式 Common Info字段 HE TB feedback NDP帧格式 NDP Feedback Report Parameter Set element格式 NDP反馈报告流程 概述 STA行为 NDP反馈报告的TXVECTOR参数 STA处理流程 NDP反馈报告流程中的Power save操作 概述 NDP反…

ipv6的NDP协议有哪些功能,是如何进行工作的

ipv6的NDP协议有哪些功能 NDP&#xff08;neighbor Discovery protocol&#xff09;是ICMPv6的子协议是IPV6协议体系中一个重要的基础协议&#xff0c;邻居发现协议替代了IPV4的ARP&#xff0c;ICMP路由器发现。它定义了使用ICMPv6报文实现地址解析&#xff0c;跟踪邻居状态&a…

IPV6邻居发现协议(NDP)

概述 NDP&#xff08;Neighbor Discovery Protocol&#xff0c;邻居发现协议&#xff09;是IPv6的一个关键协议&#xff0c;它组合了IPv4中的ARP、ICMP路由器发现和ICMP重定向等协议&#xff0c;并对它们作了改进。作为IPv6的基础性协议&#xff0c;NDP还提供了前缀发现、邻居不…

11.NDP协议分析与实践

NDP 协议分析与实践 1. 概述 1.1 简介 Neighbor Discovery Protocol 基于 ICMPv6 实现&#xff0c;用于替代 IPv4 中的 ARP 和 ICMP 路由器发现基于 ICMPv6 实现节点发现(主机和路由)、重复地址检测、地址解析、邻居不可达检测和重定向等功能 1.2 NDP 报文格式 1.2.1 路由…

IPv6邻居发现协议--NDP详解

一、ICMPv6 -Internet控制报文协议 ICMPv6是IPV6的基础协议之一&#xff0c;用于向源节点传递报文转发的信息或错误 协议类型号&#xff08;即&#xff1a;IPv6Next Header&#xff09;为58 icmpv6可以提供icmpv4的的对应功能之外&#xff0c;还有其他一些功能的基础如邻居发…

IPv6中NDP协议简介

本文介绍IPv6中一种重要协议——NDP协议。NDP协议是实现IPv6通信的重要协议之一&#xff0c;本文将详细介绍IPv6中NDP的协议实现过程和技术细节。 阅读本文&#xff0c;您需要又有一定的IPv6基础知识&#xff0c;您如果对此还存在困惑&#xff0c;欢迎查阅下列文章&#xff1a;…

5. NDP

NDP&#xff08;Neighbor Discovery Protocol&#xff09;NDP实现了IPv6中诸多重要机制。 路由器发现&#xff1a;该功能帮助设备发现链路上的路由器&#xff0c;并获得路由器通告的信息。 无状态自动配置&#xff1a;无状态自动配置是IPv6的一个亮点功能&#xff0c;它使得IP…

NDP原理详解

概述&#xff1a; 节点使用ND&#xff0c;可以确定连接在同一链路上的邻居的链路层地址&#xff0c;快速清除已经变成无效的缓存值。主机也使用ND发现能为其转发报文的路由器。最后&#xff0c;节点使用此协议主动跟踪哪一个邻居可达&#xff0c;哪一个邻居不可达&#xff0c;…

NDP 协议介绍

邻居发现协议NDP&#xff08;Neighbor Discovery Protocol&#xff09;是IPv6协议体系中一个重要的基础协议。 邻居发现协议替代了IPv4的ARP&#xff08;Address Resolution Protocol&#xff09;和ICMP路由器 发现&#xff08;RouterDiscovery&#xff09;&#xff0c;它定义了…

一文解释NDP协议(IPv6邻居发现协议)ICMPv6

目录 目录 一、前言介绍&#xff1a; 1.1、NDP简单说明&#xff1a; 1.2、ICMPv6-Internet控制报文协议 1.3、IPv6和IPv4相比有哪些优势&#xff1f; 二、IPv6邻居发现协议--NDP详解 2.1、IPv6地址解析 2.1.1、邻居请求&#xff08;Neighbor solicition&#xff09;NS …

欧拉道路与欧拉回路

1. 相关的概念如下&#xff1a; ① 有向图G为欧拉回路&#xff1a;当且仅当G的基图连通&#xff0c;且所有顶点的入度等于出度 ② 有向图G为欧拉路&#xff1a;当且仅当G的基图连通&#xff0c;而且只存在一个顶点u的入度比出度大于1&#xff0c;只存在一个顶点v的出度比入度…