SNMP++ 02-SNMP中INTEGER的BER编码与解码

本文详细介绍了SNMP中INTEGER类型的BER编码规则,包括Tag、Length和Value的编码细节。文章通过分析编码过程,解释了如何根据BER规则对INTEGER进行编码,并提供了SNMP INTEGER的编码与解码实现。此外,还探讨了编码过程中关于INTEGER高9位不能连续为0或1的限制以及在不同系统上的应用。
摘要由CSDN通过智能技术生成

 

阅读完本文你可以学到:

(1)BER 中 INTEGER 的编码规则(其中1、2、3主要引自《ASN.1编码规则详解.doc》(作者不详,该文档可在CSDN资源中搜索到))。

(2)SNMP 中 INTEGER 的编码及解码实现(主要参考 net-snmp源码和 snmp++源码)。本文仅对编码相关函数进行了详细的解释。理解它,或许是我们走向自己实现 SNMP 协议的第一步。

特别声明:

(1)感谢《ASN.1编码规则详解.doc》作者所做的工作。

(2)感谢所有为 net-snmp 及 snmp++ 作出贡献的 coders 及相关人士。

(3)文中的所有观点仅供参考。

 

一、BER 中 INTEGER 的编码规则

1、BER是什么

BER(Basic Encoding Rules)是 ASN.1 中最早定义的编码规则,在讨论编码规则时,我们是基于正确的抽象描述上。BER 传输语法的格式一直是 TLV 三元组<Type, Length, Value>。TLV 每个域都是一系列八位组,对于组合结构,其中V还可以是 TLV 三元组。BER 传输语法 是基于八位组(为了避免不同系统上的混淆,没有采用 Byte 为单位)的自定界的 编码,因为其中 L 明确界定了八位组的长度。BER 是大端编码的,其八位组的高位比特在左手边。(注:术语“大端”和“小端”表示多字节值的哪一端(小端或大端))存储在该值的起始地址。引自《UNP卷一》)。

2、Tag

INTEGER 对应的 Tag 为 0x02,占用一个八位组。

3、Length

Length有三种形式:定长短格式、定长长格式和变长格式。

定长短格式:采用定长方式,当长度不大于127个八位组时,Length 只在一个八位组中编码。

定长长格式:采用定长方式,当长度大于127个八位组时,Length 在多个八位组中编码,此时第一个八位组低七位(bit0~bit6)表示的是 Length 所占的长度,第一个八位组的最高位 bit7 为1。

变长格式:采用变长方式,Length 所在八位组固定编码为 0x80,但在 Value 编码结束后以两个 0x00 结尾。这种方式使得可以在编码没有完全结束的情况下,可以先发送部分消息个对方。

4、INTEGER 类型的值编码

按照编码规则,如果一个数值编码后大于等于两个八位组,则要求编码后的结果从 MSB(Most Significant Bit 最高有效位)开始的9个位不能是连续的0或1。

该规则是为了尽最大的可能减少 INTEGER 编码后所占的八位组个数。

可以这样理解(仅供参考)(以32位 Windows 系统上的 int 类型举例):

在 32位的 Windows 上,一个 int 类型的值占 4个字节,即占 32位。那么它对应的八位组个数就是 32 / 8 = 4。现在我想对 1进行 BER 编码,那么应该这样做:1 的十六进制为 0x00000001,如果按照通常的编码,那它编码后的结果就是 0x00000001(对应 4个八位组),但是 BER 则要求编码后的结果从 MSB开始的9个位不能是连续的0或1,这就要求我们去除一些东西。如果按照 BER 的编码规则,那它编码后的结果就是 0x01(对应 1个八位组)。

相应地,在解码时,如果待解码数值的 MSB 为 0,则如果有需要的话,它的前面应填充 0;如果待解码数值的 MSB 为 1,则如果有需要的话,它的前面应填充 1。

二、SNMP中INTEGER的编码与解码实现(在 VS2013 下演示)

1. BER(Basic Encoding Rules)所处的位置,如图1-1:

图1-1

2.  INTEGER 的 BER 编码与解码代码,并给出测试程序。

 

/************************************************************************/
/* asn1.h                                                                   */
/************************************************************************/
#pragma once

typedef unsigned char u_char;
typedef unsigned long u_long;

#define ASN_LONG_LEN 0x80

u_char* asn_build_int(u_char *data, size_t *datalength, const u_char type, long integer);
u_char* _asn_build_header(u_char *data, size_t *datalength, const u_char type, size_t length);
u_char* _asn_build_length(u_char *data, size_t *datalength, size_t length);

u_char* asn_parse_int(u_char* const data, size_t *datalength, u_char *type, long *intp);
u_char* _asn_parse_length(u_char *data, u_long *length);

 

 

/************************************************************************/
/* asn1.cpp                                                                     */
/*****
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值