OpenDPI-1.3.0源代码分析
来源:互联网 发布:西班牙 旅游 知乎 编辑:程序博客网 时间:2024/05/16 15:34
OpenDPI-1.3.0源代码分析:
1.
该main函数主要由七个子函数组成,他们分别为:
1.1
1.2
除了初始化ipoque_struct外,还会的给几个全局变量分配内存,这些全局变量包括:
osdpi_ids:所有id对应的变量,每个id用来连接一个IP与一个表示该IP的ID
osdpi_flows:所有flow对应的变量,每个flows用来连接一个flow与一个表示该flow的KEY
protocol_counter,protocol_counter_bytes:与协议相关的计数器,类型为数组
1.3
1.4
1.5
1.6
你会发现最终我们的结果存在与prot_long_str,protocol_counter,protocol_counter_bytes以及osdpi_flows这几个全局变量中,所以这几个变量我们在分析的时候需要着重分析。这些全局变量的初始化详见1.2
1.7
2.
2.1
2.2
该函数:
返回值:一个ipoque_detection_module_struct的指针,其指向的对象为该程序的核心数据结构。整个程序有且只有一个该结构
参数1:tick_per_second 这里的实参为1000,指每秒的时钟滴答(具体干什么用的不清楚,好像是用来说明cpu每秒多少个时钟滴答的)
参数2:ipoque_malloc,指定的用来分配内存的类似于malloc的函数
参数3:ipoque_debug_printf,指定的用来进行debug下的print的函数
总的来说,该函数就是用malloc函数分配了一个ipoque_detection_module_struct,该结构体中的许多成员被设定成了默认值。并返回指向该结构体的指针。注意,该函数并未让该结构体绑定回调函数。
2.3
所有的回调函数都有该函数进行绑定,大部分标志位(bitmask)的处理,也由该函数进行初始化。
下面进行具体的分析
2.3.1
2.3.2
这里的callback_buffer_size是指的回调函数的个数,为了安全起见我们现在先设置其为0,其作用可以见我下面要分析的runPcapLoop函数
2.3.3
终于,我们在这里就能看到期待已久的与具体协议有关的内容了。让我们来看一下他到底做了些什么:
注意IPOQUE_COMPARE_PROTOCOL_TO_BITMASK这个宏,在这里他的意思是:如果在detection_bitmask中设置了IPOQUE_PROTOCOL_MPEG这个标志位,那么就跳转到hack_do_http_detection去进行处理。正如之前看到的,detection_bitmask应该被设置为全1了,所以其会转到hack_do_http_detection
注意,该函数在hack_to_http_detection之前会有许多的这样的语句,因为这些协议都可以视为需要使用http_detection,所以只要有一个这样的协议定义了,就得执行http_detection
再来看看hack_to_http_detection到底做了什么吧:
首先,当然是绑定具体的处理函数啦。这些处理函数到底做了什么我们先不管,以后我会的花大量的时间分析这些处理函数,这里我们先看看其接下来做了什么。
Ipq_selection_bitmask是指如果这些协议被定义了的话,如果我们需要使用被绑定的ipoque_search_http_tcp函数,我们就需要该packet为IPV4或者IPV6,且需要拥有PAYLOAD才行。这个在我们分析完runPcapLoop后你就会清楚它是干啥的了。
接下来是对于标志位的处理:
detection_bitmask:需要detective的protocol
excluded_protocol_bitmask:排除在外不需要detective的protocol
这两个标志位在runPcapLoop就能看到其作用了,这需要与osdpi_flows连起来看才行。
在hack_do_http_detection的最后,我们看到了一句:
嗯,终于对于http的回调函数以及一些标志位的设置告一段落了。http之所以这么长是由于有太多的协议都会使用他,所以对于这些协议,我们都得用http的处理函数去处理一遍
然后其它的协议就是依样画葫芦了,比如接下来的SSL:
嗯,先是判定这个协议要不要检测,然后绑定回调函数,设置这个函数在什么时候要用,然后设置那几个标志位。是的,接下来的大部分初始化函数就只是做了这么几件事罢了,直到一些新的代码的出现:
正如注释说的一样,下面是为一些特殊的packet绑定的回调函数,这些特殊的packet主要有四种:
其做的事情也很简单,callback_buffer不是一个大杂烩嘛,那大杂烩总归有点乱,干脆再细分下好了。于是这里就把callback_buffer又细分成了四个函数,最终我们可以看到,在runPcapLoop中调用的也只是这四个函数罢了。Callback_buffer已经可以功成身退了。
2.3.4
就是初始化osdpi_flows这个全局变量,MAX_OSDPI_FLOWS在这里是200000,也就是说我们的程序最多也就只能跟踪200000条流,所以如果处理一个巨大的pacp包,这个数字可能需要适当的加大。
其它的初始化代码比较简单,就不细说了。
3.
终于轮到核心函数出场了,虽然是核心函数,但其实它并没有做什么事,真正重要的事情都让那些回调函数给做了,其不过是组织协调一些那些回调函数罢了。
3.1
一开始用的是pcap的loop函数,老套路,没什么好讲的。如果对这四个参数不熟悉的话建议上网查一查,但与我们这个程序关系不大。
3.2
这个函数的前半部分,主要是对pcap传过来的packet做些分析,然后其会的调用packet_processing
3.3
这个函数算是倒数第二个重要的函数了,所以我会的仔细的分析一下
3.3.1
3.3.2
3.3.3
有兴趣的同学可以看看ipoque_unique_flow_ipv4_and_6_struct这个结构体,看看OpenDPI是怎么定义一个flow的:
3.3.4
注意一下这几行代码,ipoque_detection_process_packet会的返回检测到的协议的类型,相应的全局变量protocol_counter和protocol_counter_bytes就会增加,然后该packet所对应的flow的类型就会被设定。
3.3.5
终于轮到这个函数出场了,我们先来看看这个函数的参数:
参数1:ipoque_struct,嗯,就是那个核心的结构体。最核心的结构体出现在最核心的函数里一点也不让人意外
参数2:flow,嗯,就是该packet对应的全局变量的那个表示flow的结构体,后者存在的目的就是为了表示该packet的一些设计flow的信息,出现在这里也完全不令人意外
参数3:packet,这个肯定得有,没有的话就不用分析了
参数4:指明packet的长度,谁叫packet是个指针呢
参数5:current_tick,我还是不知道这是干嘛的,只知道和时间有关(这个程序里和时间有关的东西我理解的都不是很好)
参数6和参数7:这两个其实是一样的,都是全局变量表示的osdpi_ids,嗯,和参数2一样,出现在这里理所应当。
既然参数我们看的都差不多懂了(除了current_tick没懂,其它参数也就只能是这么几个了,OpenDPI真的没啥其它东西可做参数了),那么分析起来就容易多了:
第一个遇到的重要函数是:ipq_init_packet_header:
他初始化了ipoque_struct->packet这个成员,并把flow中的一些信息复制到了该成员中(即让ipoque_struct->packet继承其所属的flow中的packet前辈的记忆)
然后遇到第二个重要的函数:ipoque_connection_tracking
这个函数主要设置ipoque_struct中的packet和flow的状态,有很大一部分代码和tcp的状态有关,可以详细的看一看
然后,设置ipq_selction packet bitmask,该标志位来源的依据主要来自之前对于flow和packet的分析(ipoque_connection_tracking)
换句话说,该标志位表明这个packet拥有何种属性(如是否为IP?是否为IPV4?是否有PAYLOAD?)
接下来是一句非常关键的语句:
packet->detected_protocol_stack[0]:
如果这个packet不是属于一个flow的(低于四层),那么在ipq_init_packet_header中,其会的被设置为IPOQUE_PROTOCOL_UNKNOWN:
否则,则来自于flow的继承:
最后,当这一切都处理好了之后,就是四个for循环了:
这个的意思现在再看的话就很明白不过了吧:
第一行:需要为tcp
第二行:需要payload非空
第三行:开始调用has_payload的回调函数们
第四行:进行判断,判定有无必要对这个packet调用回调函数:比如这个packet是IPV6的,但是某个has_payload的回调函数所对应的协议是绝对没有IPV6的,那么就不用大费周章的去调用了。
整个OpenDPI的demo差不多就分析到这里,下个礼拜开始看具体的协议。
=============================================================
貌似图片顺序有些问题。。。等有空再弄吧。。。嘿嘿
- OpenDPI-1.3.0源代码分析
- OpenDPI-1.3.0源代码分析
- opendpi
- opendpi 源码分析(一)
- opendpi 源码分析(二)
- opendpi 手记
- opendpi学习
- opendpi手册(读书笔记)
- 源代码分析
- 1.3. chromium源代码分析 - chromiumframe - 窗口类
- Hadoop-0.20.0源代码分析(01)
- Hadoop-0.20.0源代码分析(02)
- Hadoop-0.20.0源代码分析(03)
- Hadoop-0.20.0源代码分析(04)
- Hadoop-0.20.0源代码分析(05)
- Hadoop-0.20.0源代码分析(06)
- Hadoop-0.20.0源代码分析(07)
- Hadoop-0.20.0源代码分析(08)
- 勇气
- 程序员生存定律--成长路上常见的坑
- http2. 图解
- jquery增加,移除,修改一个html标签的class名字。
- 【JAVA大作业开发记录(四)】
- OpenDPI-1.3.0源代码分析
- InputStream的三个read的区别
- HOSt ip is not allowed to connect to this MySql server
- android studio 手动更新
- functioncharts与extjs结合,做多折线图
- mybatis的mapping基本相关操作
- 8.4 AlarmManager实现精准定时任务
- 手工实现ARP中间人攻击
- 值动画