2.1 ASN.1概述
ASN.1抽象语法标记(Abstract Syntax Notation One)是ISO/ITU-T发布的国际标准(涉及的文献有X.680~X.699),用于数据类型的定义、值的定义和数据类型的约束。由于它成熟可靠,在电信和计算机网络领域有广泛的应用。
它描述了一种对数据进行表示、编码、传输的数据格式,提供了一整套标准用于描述对象的结构,这些结构独立于具体的数据、语言、应用。也就是说,使用ASN.1描述的内容,不涉及具体的编程语言(ASN.1本身也不是编程语言)、机器的物理结构、网络的类型,即它是抽象的。而这些被描述的内容可以是文本、图片、视频等。
ASN.1除了能准确描述数据,另外非常关键的一点是,使用它表示的信息可以轻易地转化为某种具体语言(C/C++等)使用的数据表示(结构),这为结构化的数据交互提供了有效的手段。尤其适用于网络中应用程序之间的结构化数据传输,在SNMP中的应用即是如此。
由于ASN.1很抽象,它以独立计算机系统的文本来表示信息,不处理表示信息外的任何业务,以这种单一的描述功能和上层的表示方法实现抽象。但是要应用在真实的某种计算机或协议中,必然要将其表示的信息转化为计算机中可识别的数字形式。这里涉及的表示方式,可理解为OSI七层参考模型中的表示层。
抽象的东西往往不好理解,因为它表示一种“行式上的东西”,不“实际”,不过有抽象就有实际/实现,与抽象语法对应的是实际语法。
实际语法是软件开发人员所熟悉的各种编程语言的语法,这个我们很容易理解。这种实际的语法需要对应的编程语言编译器去解释,并且其中的数据在计算机内存中有具体的存放形式。不同的语言其语法是不一致的,用C编译器解释(编译)Python程序肯定是行不通的,这就是抽象语法和实际语法的差异。
依然以SNMP通信端为例,以上描述的关系可用图2-1表示(由图1-10转变而来)。
图2-1 信息定义与传输示意图
一个ASN.1源文件可以非常容易地映射为C/C++或Java数据结构。这种映射只需要通过某种具体的应用程序来实现抽象语法到实际语法的转化。在SNMP中使用ASN.1方式定义的MIB,即是对管理对象的抽象表示,转换的场景有以下两个:
1)在NMS端中完成由Agent提供的MIB文件的解释和编码,并以PDU格式与Agent通信。
2)在Agent端,如Net-SNMP代理开发中,由其提供的工具mib2c(Net-SNMP中提供的工具)完成MIB文件的解释,解释的最终结果以C语言(实际语法)表示,并传递给后续的传输编码模块使用。
如下面的一段MIB代码,经过mib2c的翻译,转化为如下的C语言中可使用的代码(只列出了转化后的数据结构,其他代码没有列出):
--MIB中某节点的定义: zcq_aaa OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS read-write STATUS current DESCRIPTION "for example. " ::={fcPara 1} // 以上MIB被翻译成了C语言中的某个结构体 struct variable4 zcqParameter_variables[] = { /* magic number, variable type , ro/rw , callbackfn , L, oidsuffix */ {ZCQ_AAA, ASN_INTEGER, RWRITE, var_zcqParameter, 2, { 1,1 }}, }
ASN.1只定义了表示信息的抽象句法,但是没有限定其编码的方法,ASN.1中可以使用多种编码规则。而SNMP中则使用BER(Basic Encoding Rules,基本编码规则)方式,更详细的内容请参考第5章。
作为一种形式语言,ASN.1本身也有相应的记法规则加以说明。实际上ASN.1由BNF(Backus-Naur Form,巴科斯范式)定义。让我们先简要地介绍BNF。