发一篇旧文。
由于常年在测试各种新业务,有时会遇到功能已经实现了,可是却没有可靠的证据来证明,秋风秋雨愁煞人。像wireshark是常用的信令分析工具,但随着3GPP的更新,会出现一些明显的错误。以F1AP为例,最新的wireshark版本声明是支持V15.0.0 (2017-12),这与我们现在使用的协议版本差距很大,其解析结果就有很多错误的地方。
这条消息里有两个IE,第一个是004e(78 in decimal),wireshark解成了unknown, 第二个IE 03,解成了F1AP ID。
查看对应版本的源代码,IE ID是这样定义的:
typedef enum _ProtocolIE_ID_enum {
id_Cause = 0,
id_CriticalityDiagnostics = 1,
id_gNB_DU_F1AP_ID = 2,
id_gNB_CU_F1AP_ID = 3,
……
id_privateMessage = 62
} ProtocolIE_ID_enum;
这里3是gNB_CU_F1AP_ID,ID最大只定义到了62。
而根据3GPP TS 38.473 V15.3.0 (2018-09),
-- **************************************************************
--
-- IEs
--
-- **************************************************************
id-Cause ProtocolIE-ID ::= 0
id-Cells-Failed-to-be-Activated-List ProtocolIE-ID ::= 1
id-Cells-Failed-to-be-Activated-List-Item ProtocolIE-ID ::= 2
id-Cells-to-be-Activated-List ProtocolIE-ID ::= 3
id-Cells-to-be-Activated-List-Item ProtocolIE-ID ::= 4
id-Cells-to-be-Deactivated-List ProtocolIE-ID ::= 5
……
id-TimeToWait ProtocolIE-ID ::= 77
id-TransactionID ProtocolIE-ID ::= 78
id-TransmissionStopIndicator ProtocolIE-ID ::= 79
……
在这里,3代表Cells-to-be-Activated-List,78代表TransactionID,显然应当根据新的协议来解log才能得到正确结果。
有没有办法让wireshark按新的协议来工作呢?一般是要等wireshark发布新的版本,但是2.6.4已经是最新的版本,下一个版本不知道何时发布,求助搜索引擎,看到有人说wireshark的开发版(非稳定版本)跟踪最新的协议,quite new,于是下到开发版,版本号是2.5.1,居然比稳定版的版本号低,找到源代码,发现包里竟然没有packet-f1ap.c文件,显然这个也不行。还有一种办法是修改源文件,然后重新编译,如果手动修改,比较麻烦也容易出错。Wireshark的开发者早就考虑到了这个问题,在wiki里提供了一种自动化的方法生成源代码。
This dissector is generated through asn2wrs script. If modification are to be done, they have to be in the template or in the configuration file.
How to generate a dissector based on a newer release:
- Download the 36331-xxx specification as Word document, open it and in "View" panel, select "normal" or "web layout" (needed to remove page header and footer) - Save it to asn1\lte-rrc directory as a text file.
- Call the asn1 extractor: perl ..\..\tools\extract_asn1_from_spec.pl 36331-xxx.txt It should generate EUTRA-RRC-Definitions.asn, EUTRA-UE-Variables.asn and EUTRA-InterNodeDefinitions.asn
- Run asn2wrs:
../../tools/asn2wrs.py -L -p lte-rrc -c lte-rrc.cnf -s packet-lte-rrc-template EUTRA-RRC-Definitions.asn EUTRA-UE-Variables.asn EUTRA-InterNodeDefinitions.asn
The packet-lte-rrc.c file is generated. Put it into the epan\dissectors folder and recompile wireshark.
在3GPP网站上能下到最新的协议,用word打开,选用“web layout“模式,然后存为txt文件。源代码包里tools目录下有两个工具,extract_asn1_from_spec可以从协议原文中摘取ASN信息,asn2wrs可以从ASN信息生成源代码,然后就可以进行编译了。
使用extract_asn1_from_spec从38.473里提供ASN,结果什么也没有生成。检查代码,里面支持25.331,38.331等,没有38.473,于是把38.473添加到代码里面去,但结果还是没有成功。
继续研究代码,就发现了很多问题,38.473没有ASN1START标记,要用别的标志来识别;38.473的字段名格式变了,代码也需要调整……经过几次调整再加一些手工编辑,终于得到了6个ASN文件。
另外,从wireshark社区支持得到的信息,wireshark主分支里F1AP的ASN.1编码是手工摘取的。好吧,手工摘取肯定是一个万能的方法。
asn2wrs生成代码需要一些配置文件和模板,经过查找在源代码包里也找到了,目录是\epan\dissectors\asn1\f1ap。运行asn2wrs过程中有报错,缺少lex,yacc,这两个是python的模块,下载PLY安装后,把asn2wrs里引用lex,yacc的语句进行了如下修改:
原文 import lex 修改为 import ply.lex as lex
原文 import yacc 修改为 import ply.yacc as yacc
然后就生成了packet-f1ap.c文件,可以看见里面的IE ID已经变成最新的了。这文件有八千多行,比原来的版本长了一倍。
id_TransactionID = 78,
接下来就是编译wireshark了。编译的步骤比较少,但是过程充满了痛苦。经过一番折腾,在百度的支持下终于编译成功。其中有几行代码报错,使用了未定义的变量,为了节省时间就将这4行代码注释掉了,做为妥协,就会有4个IE解的不完整。这个问题估计是packet-f1ap-template的问题,这文件目前还看不懂,等以后再研究吧。
然后用新编译的wireshark打开测试log,果然解对了!