Wednesday, August 14, 2013

Using C# to manage a HP GBe2c_1_10g switch via SNMP

This is to provide an example of a plug-in I wrote for the Green Monster System to manage a HP GBe2c_1_10g
. This is not the exact same as the HP_GBe2c but it is close.
The SNMP commands are performed via a base class that uses Nsoftware's SSNMP library.  That class is not included because of licensing.

If you need help or have questions feel free to send me mail.

 public bool createVlan(int tag, string name)
        {
            //Switch supports empty vlan
            //Create the vlan with tag and name
            sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.2." + tag, name);

            //Set the vlan as enabled
            sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.4." + tag, 2);
            return SaveConfig();
        }
        public bool deleteVlan(int tag)
        {
            sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.7." + tag, 2);
            return SaveConfig();
        }

        public bool addPortToVlan(int tag, int ifIndex, bool isTagged)
        {
            //if the port is to be tagged to need to set the port to tagged mode
            if (isTagged)
            {
                setPortTagMode(ifIndex, isTagged);
            }
            else //untagged membership
            {
                setPortTagMode(ifIndex, false);
                //Setting an untagged port will auto remove from other vlans and set default/native membership
            }

            sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.5." + tag, ifIndex);
            return SaveConfig();
        }

        public bool removePortFromVlan(int tag, int ifIndex)
        {
            sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.6." + tag, ifIndex);
            return SaveConfig();
        }
        public bool addFirstPorttoVlan(int tag, int ifIndex, bool isTagged, string vlanName)
        {
            //allows empty vlans so create the vlan then add the ports
            bool response = false;
            response = createVlan(tag, vlanName);
            if (response == false)
            {
                return false;
            }

            //add the port
            response = addPortToVlan(tag, ifIndex, isTagged);
            if (response == false)
            {
                return false;
            }
            return true;
        }
   public bool? isPortInVlan(int tag, int ifIndex, bool tagged)
        {

            Raw_VlanMemberCollection members = GetVlanMembers(tag);
            if (members.isErrorState == true)
                return null;

            Raw_VlanMember member = members.Find(m => m.PortifIndex == ifIndex);
            if (member == null)
                return false;

            //make sure tagging is correct
            if (member.isTagged == tagged)
                return true; //tagging matched
            else
                return false;
        }

        public Raw_VlanMemberCollection GetVlanMembers(int tag)
        {

            //The port list in the VLAN.  The ports are presented in bitmap format.
            //in receiving order:
            //OCTET 1  OCTET 2  .....
            //xxxxxxxx xxxxxxxx ..... 
            //|||||_ port 8
            //||||
            //||||___ port 7
            //|||____ port 6
            //||.    .   .
            //||_________ port 1
            //|__________ reserved
            //where x :1 - The represented port belongs to the VLAN
            //0 - The represented port does not belong to the VLAN

            Raw_VlanMemberCollection data = new Raw_VlanMemberCollection();

            byte[] vlanMembers;
            if (getSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.3.2221", out vlanMembers) == false)
            {
                data.isErrorState = true;
                return data;
            }
            ArrayList members = GetMemberPorts(vlanMembers);
            foreach (int p in members)
            {
                Raw_VlanMember member = new Raw_VlanMember();
                bool? isTagged = isPortTagged(p);
                if (isTagged == null)
                {
                    data.isErrorState = true;
                    return data;
                }
                member.isTagged = (bool)isTagged;
                member.tag = tag;
                member.port = p;
                member.slot = 1; //only supports 1 slot
                member.PortifIndex = p;
                member.VlanifIndex = tag;
                data.Add(member);
            }
            return data;
        }
        public VlanCollection getVlans()
        {
            VlanCollection vlans = new VlanCollection();
            SNMPDataCollection data = walk("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.2");
            if (data.isErrorState == true)
            {
                vlans.isErrorState = true;
                return vlans;
            }

            foreach (SNMPData obj in data)
            {
                Vlan vlan = new Vlan();
                int tag = Convert.ToInt32(obj.oid.Replace("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.1.1.3.1.2.", ""));

                string name = obj.value.ToString();
                vlan.tag = tag;
                vlan.name = name;
                if (tag != 4095) //dont add the MGMT vlan
                    vlans.Add(vlan);

            }
            return vlans;
        }
        public NetworkPortCollection getPorts()
        {

            NetworkPortCollection Ports = new NetworkPortCollection();
            //Populate ports 
            //Name  agPortCurCfgIndx
            SNMPDataCollection data = walk("1.3.6.1.4.1.11.2.3.7.11.33.5.2.1.1.2.2.1.1");
            if (data.isErrorState == true)
            {
                Ports.isErrorState = true;
                return Ports;
            }

            foreach (SNMPData obj in data)
            {
                //Check to see if the name of the port is XConnect or Mgmt

                int ifIndex = Convert.ToInt32(obj.value);
                string interfaceName;
                getSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.1.1.2.2.1.15." + ifIndex, datatypes.str, out interfaceName);
                interfaceName = interfaceName.ToLower();

                //Xconnect ports are interlinks to switch in neighbor bay
                //mgmt is management link
                if (interfaceName.IndexOf("xconnect") == -1 && interfaceName.IndexOf("mgmt") == -1)
                {
                    int slot = 0; //only has 1 slot
                    int port = ifIndex;

                    NetworkPort p = new NetworkPort();
                    p.ifIndex = ifIndex;
                    p.slotNumber = slot;
                    p.portNumber = port;
                    p.interfaceType = string.Empty;
                    p.name = interfaceName;
                    //Get the ports description
                    Ports.Add(p);
                }
            }

            return Ports;
        }

        public portStatus getPortAdminStatus(int ifIndex)
        {
            //1=enabled
            //2 = disabled
            ifIndex = ifIndex + 256;
            string data;
            if (getSNMP("1.3.6.1.2.1.2.2.1.8." + ifIndex.ToString(), datatypes.str, out data) == false)
                return portStatus.error;
            return (portStatus)Convert.ToInt32(data) - 1;
        }
        public bool setPortAdminStatus(int ifIndex, portStatus status)
        {
            ifIndex = ifIndex + 256;
            sendSNMP("1.3.6.1.2.1.2.2.1.8." + ifIndex.ToString(), Convert.ToInt32(status + 1));
            return SaveConfig();
        }

        public portStatus getPortOperationStatus(int ifIndex)
        {
            //1 = link
            //2 = no link
            ifIndex = ifIndex + 256;
            string data;
            if (getSNMP("1.3.6.1.2.1.2.2.1.8." + ifIndex.ToString(), datatypes.str, out data) == false)
                return portStatus.error;
            return (portStatus)Convert.ToInt32(data) - 1;
        }

        public bool SaveConfig()
        {
            //apply the change
            sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.1.1.1.2", 2);

            //save 
            return sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.1.1.1.4", 2);
        }

        public bool RebootDevice()
        {
            return sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.1.1.1.7", 3);
        }
    private bool setPortTagMode(int ifIndex, bool tagged)
        {
            //2=tagged
            //3=untagged
            int value = (tagged == true ? 2 : 3);
            sendSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.1.1.2.3.1.3." + ifIndex, value);
            return SaveConfig();

        }
        private bool? isPortTagged(int ifIndex)
        {
            //2=tagged
            //3=untagged
            string tagstate;
            if (getSNMP("1.3.6.1.4.1.11.2.3.7.11.33.4.2.1.1.2.3.1.3." + ifIndex, datatypes.integer, out tagstate) == false)
                return null;

            if (tagstate == "2")
                return true;
            else
                return false;
        }

        private Byte[] PORTMASKARRAY = { 128, 64, 32, 16, 8, 4, 2, 1 };

        private ArrayList GetMemberPorts(Byte[] memberbytes)
        {
            //Find out which bit positions are set in a byte.  Based off which position and byte we are in we can determine the port number
            //ie bit 7 in byte 0 = port 1
            //ie bit 0 in byte 0 = port 8
            ArrayList members = new ArrayList();

            int bytecoute = 0;
            int portNumber = 0;
            int result = 0;

            foreach (Byte b in memberbytes)
            {
                if (memberbytes[bytecoute] == 0)
                {
                    bytecoute++; // No ports where active in the Byte
                }
                else // if we have port membership in the Byte lets see which ports
                {

                    for (int i = 0; i < 8; i++) // Loop through each bit 
                    {
                        result = memberbytes[bytecoute] & PORTMASKARRAY[i]; // Is each bit value (port) in the array?
                        if (result == PORTMASKARRAY[i])
                        {
                            portNumber = i + bytecoute * 8;
                            members.Add(portNumber); // Add the portnumber to our returned list
                        }
                    }
                    bytecoute++;
                }
            }
            return members;
        }

        public int getPortifIndexbyMAC(string MACAddress)
        {
            //OID for iFIndex
            string oid = string.Empty;

            //Replace : and . with space
            MACAddress = MACAddress.Replace(":", "").Replace(".", "").Replace(" ", "").Replace("-", "");

            SNMPDataCollection data = walk("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.3.2.2.1.1", true);
            if (data.isErrorState == true)
                return -1;

            foreach (SNMPData item in data)
            {
                if (ConvertToHex(item.value).ToLower() == MACAddress.ToLower())
                {
                    oid = item.oid.Replace("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.3.2.2.1.1.", "");
                    break;
                }
            }
            //make sure we found an OID
            if (oid == string.Empty)
                return -1;

            int i = -1;
            //look up the fdb port number
            string ifIndex;
            if (getSNMP("1.3.6.1.4.1.11.2.3.7.11.33.5.2.2.3.2.2.1.3." + oid, datatypes.integer, out ifIndex) == false)
                return -1;

            if (ifIndex == "-1" || ifIndex == string.Empty)
                return -1;
            else
                //Take the FDB base port number and get the ifIndex for the interface

                if (Int32.TryParse(ifIndex, out i) == false)
                    return -1;
                else
                    return i; //return the index

        }
        private string ConvertToHex(object bytearray)
        {

            byte[] ba = (byte[])bytearray;

            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }

        #region ISwitchMangement Members


        public Raw_FDBEntryCollection GetFDB()
        {
            throw new NotImplementedException();
        }

        #endregion

No comments: