正确解析MAC地址

时间:2019-07-08 21:27:59

标签: sharp-snmp

当我使用snmp-walk或snmp-get之类的工具查询返回类型为MacAddress的OID时,它将始终将数据解析为HexString并正确显示。即使没有加载MIB​​,它仍然可以工作。

bash#snmpwalk -v 2c -c public 10.1.2.3 1.3.6.1.4.1.14179.2.2.1.1
    SNMPv2-SMI::enterprises.14179.2.2.1.1.1.16.189.24.206.212.64 = Hex-STRING: 10 BD 18 CE D4 40 
    SNMPv2-SMI::enterprises.14179.2.2.1.1.1.100.233.80.151.114.192 = Hex-STRING: 64 E9 50 97 72 C0 

但是,我似乎无法从Lextm.SharpSnmpLib (11.2.0)得到相同的结果。 MacAddress的数据类型无法正确解码,这是将其转换为正确的MAC的手动过程。

public void WalkTable()
    {
    const string baseOid = "1.3.6.1.4.1.14179.2.2.1.1"; //The entire table
    const string community = "public";

    var ep = new IPEndPoint(IPAddress.Parse("10.1.2.3"), 161);
    var results = new List<Variable>();
    Messenger.Walk(VersionCode.V2, ep, new OctetString(community), new ObjectIdentifier(baseOid), results, 60000, WalkMode.WithinSubtree);

    foreach(var v in results)
    Console.WriteLine(v.Data.ToString());
    }   

Incorrect Results

我做错什么了吗?或者这只是库的工作原理吗?


1 个答案:

答案 0 :(得分:1)

您正在将MAC地址输出为ASCII而不是十六进制。这是我汇总的一种快速方法,该方法将检测非ASCII字符,并在发现任何字符时将其输出为十六进制。

public void WalkTable()
    {
    const string baseOid = "1.3.6.1.4.1.14179.2.2.1.1"; //The entire table
    const string community = "public";

    var ep = new IPEndPoint(IPAddress.Parse("10.1.2.3"), 161);
    var results = new List<Variable>();
    Messenger.Walk(VersionCode.V2, ep, new OctetString(community), new ObjectIdentifier(baseOid), results, 60000, WalkMode.WithinSubtree);

    foreach(var v in results)
        //If the result is an OctetString, check for ascii, otherwise use ToString()
        Console.WriteLine(v.Data.TypeCode.ToString()=="OctetString" ? DecodeOctetString(v.Data.ToBytes()) : v.Data.ToString())
    }
}

public string DecodeOctetString(byte[] raw)
{
    //First 2 bytes are the Type, so remove them
    byte[] bytes = new byte[raw.Length - 2];
    Array.Copy(raw, 2, bytes, 0, bytes.Length);

    //Check if there are any non-ascii characters
    bool ascii = true;
    foreach (char c in Encoding.UTF8.GetString(bytes))
    {
        if (c >= 128)
        {
            ascii = false;
        }
    }

    //If it's all ascii, return as ascii, else convert to hex
    return ascii ? Encoding.ASCII.GetString(bytes) : BitConverter.ToString(bytes);
}