sharp-snmp

Properly parse MAC Address


When I use tools such as snmp-walk or snmp-get to query an OID with a return type of MacAddress, It'll always parse the data as a HexString and display it properly. Even when they don't have the MIBs loaded it'll still works.

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 

However, I can't seem to get the same result from Lextm.SharpSnmpLib (11.2.0). Data types of MacAddress don't get decoded correctly and it's a manual process to convert it to a proper 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

Am I doing something wrong or is this just how the library works?



Solution

  • You are outputting the MAC Address as ASCII instead of Hex. Here's a quick method I put together that will detect non-ascii characters and output as hex if any are found.

    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);
    }