奇怪的SNMP转换操作
本文关键字:转换 操作 SNMP | 更新日期: 2023-09-27 18:19:34
以下内容来自Richard Blum的《C#网络编程》一书:
public byte[] get(string request, string host, string community, string_ mibstring)
{
byte[] packet = new byte[1024];
byte[] mib = new byte[1024];
int snmplen;
int comlen = community.Length;
string[] mibvals = mibstring.Split('.');
int miblen = mibvals.Length;
int cnt = 0, temp, i;
int orgmiblen = miblen;
int pos = 0;
// Convert the string MIB into a byte array of integer values
// Unfortunately, values over 128 require multiple bytes
// which also increases the MIB length
for (i = 0; i < orgmiblen; i++)
{
temp = Convert.ToInt16(mibvals[i]);
if (temp > 127)
{
mib[cnt] = Convert.ToByte(128 + (temp / 128));
mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128));
cnt += 2;
miblen++;
}
else
{
mib[cnt] = Convert.ToByte(temp);
cnt++;
}
}
snmplen = 29 + comlen + miblen - 1; //Length of entire SNMP packet
//The SNMP sequence start
packet[pos++] = 0x30; //Sequence start
packet[pos++] = Convert.ToByte(snmplen - 2); //sequence size
//SNMP version
packet[pos++] = 0x02; //Integer type
packet[pos++] = 0x01; //length
packet[pos++] = 0x00; //SNMP version 1
//Community name
packet[pos++] = 0x04; // String type
packet[pos++] = Convert.ToByte(comlen); //length
//Convert community name to byte array
byte[] data = Encoding.ASCII.GetBytes(community);
for (i = 0; i < data.Length; i++)
{
packet[pos++] = data[i];
}
}
我不理解以下代码:
for (i = 0; i < orgmiblen; i++)
{
temp = Convert.ToInt16(mibvals[i]);
if (temp > 127)
{
mib[cnt] = Convert.ToByte(128 + (temp / 128));
mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128));
cnt += 2;
miblen++;
}
else
{
mib[cnt] = Convert.ToByte(temp);
cnt++;
}
}
我知道这是为了在temp大于一个字节的情况下将其放入两个字节。但是,128+(temp/128)的计算是什么,然后是第二个字节:temp-(temp/122)*128,这是我不明白的。
请帮忙,谢谢。
如果temp大于127,那么它将被拆分为2个字节。让我们看看2个例子/
temp = 100;
128 + (temp / 128); //(temp / 128) = 0 + 128 so the mib[cnt] is set to 128
temp - ((temp/128) * 128); // 0*128 = 0. subtracted from temp leaves the original. so you end up with
mib[cnt] = 128;
mib[cnt+1] = 100;
现在,如果温度>127
temp = 200;
128 + (temp / 128); //(temp / 128) = 1 + 128 so the mib[cnt] is set to 129
temp - ((temp/128) * 128); // 1*128 = 128. 200-128 = 72. so you end up with
mib[cnt] = 129;
mib[cnt+1] = 72;
因此,基本上,它需要一个数字,测试它是否大于7字节(-128=>+127是一个有符号字节),如果您提供的数字会溢出该范围,它会将其转换为2字节值/
以下引用自了解SNMP MIB第394页,因为本书比其他任何书都更好地描述了技术细节,
编码的OBJECT IDENTIFIER由编码和连接的原始值中的每个子标识符组成。每个子标识符被编码为一系列八位字节,如下所示,
- 每个八位字节中的比特8通过将该比特设置为0来指示它是否是子标识符的最后一个八位字节
- 八位位组中的第7位到第1位在级联时形成子标识符的值
- 子标识符中的第一个八位位组可能不具有值80(以HEX表示)。这确保了最小数量的八位字节用于编码。值80(以HEX表示)将指示后面有更多的八位字节,但值位(7-1)被设置为零
问题正文中粘贴的源代码实际上遵循了解析字节的规则。因此,如果你理解了规则,你就可以理解代码。
(更新:规则来自ITU-T X.690、ISO/IEC 8825-1。)
这适用于所有值:
for (i = 0; i < orgmiblen; i++)
{
temp = Convert.ToInt64(mibvals[i]);
int k = (int)Math.Log((Double)temp, (Double)2) / 7;
miblen += k;
int continuation = 0;
do
{
mib[cnt++ + k] = Convert.ToByte((temp & 127) + continuation);
temp = ((int)(temp / 128));
continuation = 128;
k -= 2;
}
while (temp > 0);
}