ASN.1 简介
ASN.1 是一种计算机语言,由 CCITT/ITU 用于规范数据类型和值,尤其是在通信中 协议。 虽然它是为 OSI 表示层设计的, 它可以用于许多其他目的,例如较低的 OSI 层协议 和许多其他协议架构。
ASN.1 通常用于定义协议 通信协议的数据单元 (PDU)。 将 PDU 映射到 具体的八位字节序列,ASN.1 标准提供了几种编码 规则。 有两个主要的编码规则:
- 基本编码规则(BER):基本编码规则 在 PDU 的每个组件前面加上一个识别标签和数据长度。 这些编码规则非常简单但占用空间,而且大多 用于旧标准中的编码。
- 打包编码规则 (PER):打包编码 规则以非常紧凑的格式对值进行编码,并且通常使用最小值 所需的位数。 这些编码规则非常复杂,并且 主要用于最近的标准。
ASN.1 编译器支持这两种编码规则 (及其变体,如 CER 和 DER)并生成数据类型、值、编码、 和特定编程语言(C 或 Java)的解码函数 根据用户提供的 ASN.1 文件中的定义。
文献:官网说明
工具: 在线解码
c库 :fast-ber;asn1C
本文主要以asn1c为主
编译
依赖说明
强烈建议使用64位的构建系统进行asn1c操作。
-
编译器
需要一个C99编译器来编译asn1c,比如gcc-4.x或clang-3.4。asn1c编译器生成c90兼容的代码,它也向上兼容c++。 -
依赖包
个符号指定了所需的最小包版本(-ver)或精确版本(=ver)。例如,bison=2.x需要bison的2.x 分支,不是3.x。- automake-1.15
- libtool
- bison=2.x
- flex
-
编译asn1c生成的代码
- C: 至少需要一个支持C90的编译器。几乎任何现代C编译器都可以,但建议使用gcc或clang。注意msvc++不是一个C编译器。
- C++: 推荐使用c++ 11兼容的编译器。
编译
- 配置
test -f configure || autoreconf -iv
./configure
- 编译安装
make
sudo make install
man asn1c
asn1c(1) Version 0.9.28 asn1c(1)
NAME
asn1c -- the ASN.1 Compiler
SYNOPSIS
asn1c [-E [-F] | -P | -R]
[-Sdir] [-X]
[-Wdebug-...] [-foption] [-gen-option] [-pdu={all|auto|Type}]
[-print-option]
input-filenames...
DESCRIPTION
asn1c compiles ASN.1 specifications into a set of target language (C/C++) encoders and decoders for BER, DER, PER, XER and other encoding rules.
OPTIONS
Stage Selection Options
-E Run the parsing stage only. Print the reconstructed ASN.1 text.
-F Used together with -E, instructs the compiler to stop after the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1
specification to the standard output.
-P Dump the compiled output to the standard output instead of creating the target language files on disk.
-R Restrict the compiler to generate only the ASN.1 tables, omitting the usual support code.
-S directory
Use the specified directory with ASN.1 skeleton files.
-X Generate an XML DTD schema for the specified ASN.1 files.
Warning Options
-Werror
Treat warnings as errors; abort if any warning is produced.
-Wdebug-lexer
Enable lexer debugging during the ASN.1 parsing stage.
-Wdebug-fixer
Enable ASN.1 syntax tree fixer debugging during the fixing stage.
-Wdebug-compiler
Enable debugging during the actual compile time.
Language Options
-fbless-SIZE
Allow SIZE() constraint for INTEGER, ENUMERATED, and other types for which this constraint is normally prohibited by the standard. This is
a violation of ASN.1 standard, and the compiler may fail to produce a meaningful code.
-fcompound-names
Using this option prevents name collisions in the target source code by using complex names for target language structures. (Name
collisions may occur if the ASN.1 module reuses the same identifiers in multiple contexts).
-findirect-choice
When generating code for a CHOICE type, compile the CHOICE members as indirect pointers instead of declaring them inline. Consider using
this option together with -fno-include-deps to prevent circular references.
-fincludes-quoted
Refer to header files in #includes using "double" instead of <angle> quotes.
-fknown-extern-type=name
Pretend the specified type is known. The compiler will assume the target language source files for the given type have been provided
manually.
-fline-refs
Include ASN.1 module's line numbers in generated code comments.
-fno-constraints
Do not generate ASN.1 subtype constraint checking code. This may make a shorter executable.
-fno-include-deps
Do not generate courtesy #include lines for non-critical type dependencies. Helps prevent namespace collisions.
-funnamed-unions
Enable unnamed unions in the definitions of target language's structures.
-fwide-types
Use the unbounded size data types (INTEGER_t, ENUMERATED_t, REAL_t) by default, instead of using the native machine's data types (long,
double).
Codecs Generation Options
-gen-PER
Generate the Packed Encoding Rules (PER) support code.
-pdu={all|auto|Type}
Create a PDU table for specified types, or discover Protocol Data Units automatically. In case of -pdu=all, all ASN.1 types defined in all
modules will form a PDU table. In case of -pdu=auto, all types not referenced by any other type will form a PDU table. If Type is an ASN.1
type identifier, the identifier is added to the generated PDU table. The last form may be specified multiple times to add any number of
PDUs.
Output Options
-print-constraints
When -EF options are also specified, this option forces the compiler to explain its internal understanding of subtype constraints.
-print-lines
Generate "-- #line" comments in -E output.
SEE ALSO
unber(1), enber(1).
AUTHORS
Lev Walkin <vlm@lionet.info>.
ASN.1 Compiler 2016-01-23 asn1c(1)
使用
新建一个asn的文件
文件名称为MyModule.asn1
MyModule DEFINITIONS ::=
BEGIN
MyTypes ::= SEQUENCE {
myObjectId OBJECT IDENTIFIER,
mySeqOf SEQUENCE OF MyInt,
myBitString BIT STRING {
muxToken(0),
modemToken(1)
}
}
MyInt ::= INTEGER (0..65535)
END
编译asn文件
asn1c MyModule.asn1
编译完成会在当前目录生成很多的*.c
和*.h
文件
俩种方式
使用自定义的main函数
注:此种方式请将converter-sample.c
移除当前目录,因为这个函数中也有main函数
- 新建一个a.c 文件,敲入代码如下
#include <stdio.h> /* for stdout */
#include <stdlib.h> /* for malloc() */
#include <assert.h> /* for run-time control */
#include "MyTypes.h" /* Include MyTypes definition */
int main() {
/* Define an OBJECT IDENTIFIER value */
int oid[] = { 1, 3, 6, 1, 4, 1, 9363, 1, 5, 0 }; /* or whatever */
/* Declare a pointer to a new instance of MyTypes type */
MyTypes_t *myType;
/* Declare a pointer to a MyInt type */
MyInt_t *myInt;
/* Temporary return value */
int ret;
/* Allocate an instance of MyTypes */
myType = calloc(1, sizeof *myType);
assert(myType); /* Assume infinite memory */
/*
* Fill in myObjectId
*/
ret = OBJECT_IDENTIFIER_set_arcs(&myType->myObjectId,
oid, sizeof(oid[0]), sizeof(oid) / sizeof(oid[0]));
assert(ret == 0);
/*
* Fill in mySeqOf with a couple of integers.
*/
/* Prepare a certain INTEGER */
myInt = calloc(1, sizeof *myInt);
assert(myInt);
*myInt = 123; /* Set integer value */
/* Fill in mySeqOf with the prepared INTEGER */
ret = ASN_SEQUENCE_ADD(&myType->mySeqOf, myInt);
assert(ret == 0);
/* Prepare another integer */
myInt = calloc(1, sizeof *myInt);
assert(myInt);
*myInt = 111222333; /* Set integer value */
/* Append another INTEGER into mySeqOf */
ret = ASN_SEQUENCE_ADD(&myType->mySeqOf, myInt);
assert(ret == 0);
/*
* Fill in myBitString
*/
/* Allocate some space for bitmask */
myType->myBitString.buf = calloc(1, 1);
assert(myType->myBitString.buf);
myType->myBitString.size = 1; /* 1 byte */
/* Set the value of muxToken */
myType->myBitString.buf[0] |= 1 << (7 - myBitString_muxToken);
/* Also set the value of modemToken */
myType->myBitString.buf[0] |= 1 << (7 - myBitString_modemToken);
/* Trim unused bits (optional) */
myType->myBitString.bits_unused = 6;
/*
* Print the resulting structure as XER (XML)
*/
xer_fprint(stdout, &asn_DEF_MyTypes, myType);
return 0;
}
- 编译所有的
.c
文件
cc -o my-program -I. *.c
- 运行
$ ./my-program
<MyTypes>
<myObjectId>1.3.6.1.4.1.9363.1.5.0</myObjectId>
<mySeqOf>
<MyInt>123</MyInt>
<MyInt>111222333</MyInt>
</mySeqOf>
<myBitString>
11
</myBitString>
</MyTypes>
使用生成converter-sample.c
文件
使用生成的converter-sample.c
要先移除自己的包含main函数的文件
- 编译
直接cc -I. -o test *.c
可能会出现连接的标识符未定义的情况(asn_DEF_PDU),此时需要指定下你的pdu,这个玩意得看你自定义的*.asn文件中的定义。解决办法来源
例如:
假如你的asn文件定义如图所示,即MyTypes ::= SEQUENCE {...}
中的内容,那么这个youpdu就是MyTypes
,这样pdu 就能找见这个标识符啦。
应执行的编译命令如下;
cc -I. -DPDU=MyTypes -o test *.c
- 运行
问题
-
asn1c是否支持BER 编码?我在文档中只看到DER编码
答: 是的,asn1c编译器完全支持BER编码。从接收方的角度来看,任何DER编码的数据,根据定义,都是有效的BER 数据。
如果希望对数据进行BER或DER编码,只需调用der_encode()。 -
我的连接器报错:未定义的符号:_asn_DEF_PDU
/usr/bin/ld: /tmp/ccDIus7C.o:(.data.rel+0x0): undefined reference to 'asn_DEF_PDU'
答:如果您有自己的带有main()例程的文件,只需删除converter-sample.c文件,您就不需要它了。如果你自己还没有创建main()例程,并且希望依赖converter-sample.c来满足你的代码转换需求,可以在编译器标志列表中添加-DPDU=YourPdu。
-
如何编制3GPP无线电资源控制规范?
asn1c发行版包含一个RRC 25.331(版本7.1.0)示例,请查看sample.source.RRC。你也可以使用预编译的rrc-dump.exe程序,它是Windows ASN.1编译器安装程序的一部分。 -
How to compile the ISO 13522 (MHEG-5) specification?
ASN.1编译器附带MHEG-5解码器。按照https://github.com/vlm/asn1c/tree/master/examples/sample.source.MHEG5 README文件的说明操作。您还可以使用预编译的mheg5dump.exe程序,它是Windows ASN.1编译器安装程序的一部分。 -
How to compile the XYZ decoder?
如果XYZ是MEGACO(媒体网关控制)中的一个,PKIX1/X。509, LDAP, GSM TAP3或OAM ULP,只要去example /sample.source。XYZ,然后运行“make”。Windows ASN.1编译器安装程序已经包含了这些编码格式的预编译解码器。