Showing posts with label Networking. Show all posts
Showing posts with label Networking. Show all posts

Wednesday, August 14, 2013

Using C# to manage a Brocade TurboIron switch via SNMP

This is to provide an example of a plug-in I wrote for the Green Monster System to manage a Brocade TurboIron switch.

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)
        {
            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.1." + tag, name, datatypes.str)); //Set Vlan Name
            request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.2." + tag, new Byte[1], datatypes.str)); //Egress Members
            request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.4." + tag, new Byte[1], datatypes.str)); //Untagged Members
            request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.5." + tag, 4, datatypes.integer)); //Create and Go

            return sendSNMP(request);
        }
        public bool deleteVlan(int tag)
        {
            try
            {
                return sendSNMP("1.3.6.1.2.1.17.7.1.4.3.1.5." + tag, 6);
            }
            catch (Exception)
            {
                //return false;
                throw;
            }
        }

        public bool addPortToVlan(int tag, int ifIndex, bool isTagged)
        {
            try
            {
                Byte[] currentMembers;
                if (GetQBridgeVlanMembers(tag, isTagged, out currentMembers) == false)
                    return false;

                if (currentMembers.Length == 0)
                    return false; //vlan needs to be created first

                currentMembers = this.GeneratePortByteStream(ifIndex, currentMembers, true);
                //Due to bug in TI code
                //Issue is that QBridge Add port to vlan logic does not check if target port is tagged 
                //So if target port is already member of another vlan as tagged it will fail on all other adds

                //Workaround is to use 1.3.6.1.4.1.1991.1.1.3.2.6.1.3.. i 4 to add the port to the vlan after it is added via qbridge to first

                //If we are doing tagged we need to do workaround
                if (isTagged)
                {
                    //check to see if target port is already member of another vlan
                    if (isPortTaggedinAnotherVlan(ifIndex) == true)//add with private OID
                        return sendSNMP("1.3.6.1.4.1.1991.1.1.3.2.6.1.3." + tag + "." + ifIndex, 4);

                    //if this did not find and return fall through to qbridge
                }

                return SetQBridgeVlanMembers(currentMembers, tag, isTagged);

            }
            catch (Exception e)
            {
                // return false;
                throw e;
            }
        }
        public bool removePortFromVlan(int tag, int ifIndex)
        {
            try
            {
                return sendSNMP("1.3.6.1.4.1.1991.1.1.3.2.6.1.3." + tag + "." + ifIndex, 3);

            }
            catch (Exception e)
            {
                //return false;
                throw e;
            }
        }
 public bool? isPortInVlan(int tag, int ifIndex, bool tagged)
        {
            Raw_VlanMemberCollection members = GetVlanMembers(tag);
            if (members.isErrorState == true)
                return null;

            if (members.Find(v => v.PortifIndex == ifIndex && v.isTagged == tagged) != null)
                return true;
            else
                return false;

        }

        public VlanCollection getVlans()
        {
            VlanCollection Vlans = new VlanCollection();
            SNMPDataCollection data = walk("1.3.6.1.4.1.1991.1.1.3.2.7.1.1");
            if (data.isErrorState == true)
            {
                Vlans.isErrorState = true;
                return Vlans;
            }

            foreach (SNMPData obj in data)
            {
                string vlanTag = obj.value.ToString(); //each value will be a vlan
                string oid = obj.oid;
                int ifIndex = Convert.ToInt32(vlanTag); //Foundry uses the Tag as the ifIndex

                //Will include 4095 which is the Management Vlan
                Vlan vlan = new Vlan();
                vlan.tag = Convert.ToInt32(vlanTag);
                vlan.ifIndex = Convert.ToInt32(ifIndex);
                vlan.name = getVlanName(vlan.tag);
                Vlans.Add(vlan);
            }

            return Vlans;
        }

        public Raw_VlanMemberCollection GetVlanMembers(int tag)
        {
            Raw_VlanMemberCollection data = new Raw_VlanMemberCollection();

            //Get untagged port members
            byte[] vlanMembers;
            if (GetQBridgeVlanMembers(tag, false, out vlanMembers) == false)
            {
                data.isErrorState = true;
                return data;
            }

            ArrayList members = GetMemberPorts(vlanMembers);
            foreach (int p in members)
            {
                Raw_VlanMember member = new Raw_VlanMember();
                member.isTagged = false;
                member.tag = tag;
                member.port = p;
                member.slot = 1; //only supports 1 slot
                member.PortifIndex = p;
                member.VlanifIndex = tag;
                data.Add(member);
            }

            //Get Tagged members

            if (GetQBridgeVlanMembers(tag, true, out vlanMembers) == false)
            {
                data.isErrorState = true;
                return data;
            }
            members = GetMemberPorts(vlanMembers);
            foreach (int p in members)
            {
                Raw_VlanMember member = new Raw_VlanMember();
                member.isTagged = true;
                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 NetworkPortCollection getPorts()
        {
            NetworkPortCollection Ports = new NetworkPortCollection();
            SNMPDataCollection data = walk("1.3.6.1.4.1.1991.1.1.3.3.5.1.18");
            if (data.isErrorState == true)
            {
                Ports.isErrorState = true;
                return Ports;
            }

            foreach (SNMPData obj in data) //Get all our ports
            {
                string value = obj.value.ToString();

                //static devices dont return slot info
                if (value.IndexOf(@"/") == -1) //we are not doing a moduler device
                {
                    value = @"1/" + value; //set default slot to 1
                }


                //Value returned looks like /
                //Lets split it out
                string[] slotport = value.Split(Convert.ToChar(@"/"));
                int id = Convert.ToInt32(obj.oid.ToString().Substring(obj.oid.ToString().LastIndexOf(".") + 1));


                NetworkPort port = new NetworkPort(id, Convert.ToInt32(slotport[0]), Convert.ToInt32(slotport[1]));
                port.name = getPortDescription(port.ifIndex);
                port.adminStatus = getPortAdminStatus(port.ifIndex);
                port.operationStatus = getPortOperationStatus(port.ifIndex);
                if (port.unTaggedVlan == null)
                {
                    port.unTaggedVlan = new VlanMember();
                }
                port.unTaggedVlan.tag = getPortUntaggedVlan(port.ifIndex);

                Ports.Add(port);
            }

            return Ports;
        }
        public bool addFirstPorttoVlan(int tag, int ifIndex, bool isTagged, string vlanName)
        {
            try
            {
                SNMPDataCollection request = new SNMPDataCollection();

                request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.1." + tag, vlanName, SNMPBase.datatypes.str)); //Vlan Name
                request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.2." + tag, new byte[1], SNMPBase.datatypes.str)); //Egress Ports

                if (isTagged)
                    request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.4." + tag, new byte[1], SNMPBase.datatypes.str)); //Untagged ports

                request.Add(new SNMPData("1.3.6.1.2.1.17.7.1.4.3.1.5." + tag, 4, SNMPBase.datatypes.integer)); //CreateAndGo
                bool response = sendSNMP(request);

                return addPortToVlan(tag, ifIndex, isTagged);
            }
            catch (Exception)
            {
                return false;
                throw;
            }
        }
        private int getPortUntaggedVlan(int ifIndex)
        {
            string data;
            if (getSNMP("1.3.6.1.4.1.1991.1.1.3.3.5.1.24." + ifIndex.ToString(), SNMPBase.datatypes.integer, out data) == false)
                return -1;
            return Convert.ToInt32(data);
        }
  #region "Private"
        private bool isPortTaggedinAnotherVlan(int ifIndex)
        {
            VlanCollection vlans = getVlans();
            foreach (Vlan vlan in vlans)
            {
                Raw_VlanMemberCollection members = GetVlanMembers(vlan.tag);
                Raw_VlanMember member = members.Find(m => m.PortifIndex == ifIndex && m.isTagged == true);
                if (member != null)
                    return true; //found a member
            }

            return false; //port is not any other vlans

        }
        private static readonly 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 + 1 + bytecoute * 8;
                            members.Add(portNumber); // Add the portnumber to our returned list
                        }
                    }
                    bytecoute++;
                }
            }
            return members;
        }

        private static bool isPortMember(int portnumber, Byte[] membershipstream)
        {
            //Determine the port number we are working with for the given slot
            //Mod by 1000 to remove slot number; set remainder to portnumber
            portnumber %= 1000;

            //Byte[] PORTMASKARRAY = { 128, 64, 32, 16, 8, 4, 2, 1 };
            return (membershipstream[(portnumber - 1) / 8] & PORTMASKARRAY[(portnumber - 1) % 8]) != 0;
        }
        private bool GetQBridgeVlanMembers(int tag, bool isTagged, out  Byte[] members)
        {
            members = new Byte[0];
            if (isTagged)
            {

                byte[] allmembers;
                getSNMP("1.3.6.1.2.1.17.7.1.4.2.1.4.0." + tag, out allmembers); //dot1qVlanStaticEgressPorts
                //dot1qVlanStaticEgressPorts also includes untagged ports.  So we have to remove the untagged ports from the array.
                //What is left will be the tagged only ports
                byte[] untaggedMembers;
                if (GetQBridgeVlanMembers(tag, false, out untaggedMembers) == false)
                    return false;

                byte[] taggedports = new byte[allmembers.Length];
                for (int i = 0; i < allmembers.Length; i++)
                {
                    taggedports[i] = Convert.ToByte(allmembers[i] ^ untaggedMembers[i]);
                }

                members = taggedports;
                return true;
            }
            else
            {
                byte[] untaggedMembers;
                if (getSNMP("1.3.6.1.2.1.17.7.1.4.2.1.5.0." + tag, out untaggedMembers) == false) //dot1qVlanStaticUntaggedPorts
                    return false;

                members = untaggedMembers;
                return true;
            }
        }

        private bool SetQBridgeVlanMembers(Byte[] members, int tag, bool isTagged)
        {
            //Allways add Vlan member to Egress port.  By default is tagged.  If you want untagged then also add to untaggedPorts
            bool result = false;

            if (isTagged)
            {
                return sendSNMP("1.3.6.1.2.1.17.7.1.4.3.1.2." + tag, members, datatypes.str); //dot1qVlanStaticEgressPorts
            }
            else
            {
                //for egreess ports we need to get all current egress ports to append the current port
                Byte[] currentMembers;
                if (GetQBridgeVlanMembers(tag, true, out currentMembers) == false)
                    return false;

                if (currentMembers.Length == 0)
                    return false; //vlan needs to be created first

                result = SetQBridgeVlanMembers(currentMembers, tag, true);
                if (result == false)
                    return false;

                result = sendSNMP("1.3.6.1.2.1.17.7.1.4.3.1.4." + tag, members, datatypes.str); //dot1qVlanStaticUntaggedPorts

            }
            return result;
        }
        /// 
        /// QBridge Byte Stream generation, used for modifing port membership in Vlan
        /// 
        /// portnumber to add/remove from vlan
        /// 
        private Byte[] GeneratePortByteStream(int newMemberPort, Byte[] currentMembers, bool addPort)
        {
            //Determine the port number we are working with for the given slot
            //Mod by 1000 to remove slot number; set remainder to portnumber
            //portnumber %= 1000;
            Byte[] holdingByte = new Byte[currentMembers.Length];
            Array.Copy(currentMembers, holdingByte, currentMembers.Length);


            //Determin which byte we are working with
            int byteposition = (newMemberPort - 1) / 8;

            //Mod to find the bit we are working with 
            int maskindex = (newMemberPort - 1) % 8;

            //Set the value in our Holding array for the corresponding bit
            if (addPort)
                holdingByte[byteposition] |= PORTMASKARRAY[maskindex];
            else
            {
                if ((holdingByte[byteposition] & PORTMASKARRAY[maskindex]) == 0) //check to see if the newMemberport is a member of the currentMembers
                    return holdingByte;


                if (currentMembers[byteposition] == 0)  //dont xor a null value.  If the port is not already a member dont try to remove it.
                    return holdingByte;
                // holdingByte[byteposition] = Convert.ToByte(currentMembers[byteposition] & INVERTED_PORTMASKARRAY[maskindex]);
                holdingByte[byteposition] = Convert.ToByte(currentMembers[byteposition] ^ PORTMASKARRAY[maskindex]);
            }
            return holdingByte;
        }

        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();
        }
        #endregion

Using C# to manage an Extreme Extremeware based switch via SNMP

This is to provide an example of a plug-in I wrote for the Green Monster System to manage an Extreme Networks ExtremeWare based switch.  This is there older line of switches

Most of these commands were determined via many hours with network sniffer as the MIBs do not expose the OIDs used here.

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)
        {
            //1.3.6.1.4.1.1916.1.2.1.2.1.1.22016 i 22016 
            //1.3.6.1.4.1.1916.1.2.1.2.1.2.22016 s testvlan 
            //1.3.6.1.4.1.1916.1.2.1.2.1.3.22016 i 1 
            //1.3.6.1.4.1.1916.1.2.1.2.1.4.22016 i 22016 
            //1.3.6.1.4.1.1916.1.2.1.2.1.6.22016 i 4

            //Get new Index

            //1.3.6.1.4.1.1916.1.2.3.1.1.2.22018 i 1 
            //1.3.6.1.4.1.1916.1.2.3.1.1.3.22018 i 124 
            //1.3.6.1.4.1.1916.1.2.3.1.1.4.22018 i 4

            //1.3.6.1.2.1.31.1.2.1.1.22016.22018 i 22016 
            //1.3.6.1.2.1.31.1.2.1.2.22016.22018 i 22018 
            //1.3.6.1.2.1.31.1.2.1.3.22016.22018 i 4

            //Query to get the next available index for this switch
            int index1 = getAvailableIndex();
            if (index1 == -1)
                return false;

            bool results = false;
            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.1." + index1, index1, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.2." + index1, name, SNMPBase.datatypes.str));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.3." + index1, 1, SNMPBase.datatypes.integer)); //Vlan Type
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.4." + index1, index1, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.6." + index1, 4, SNMPBase.datatypes.integer)); //Vlan status
            results = sendSNMP(request);

            if (results == false)
                return false;

            int index2 = getAvailableIndex();
            if (index2 == -1)
                return false;

            request = new SNMPDataCollection();

            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.3.1.1.2." + index2, 1, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.3.1.1.3." + index2, tag, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.3.1.1.4." + index2, 4, SNMPBase.datatypes.integer));
            results = sendSNMP(request);
            if (results == false)
                return false;

            request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.2.1.31.1.2.1.1." + index1 + "." + index2, index1, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.2.1.31.1.2.1.2." + index1 + "." + index2, index2, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.2.1.31.1.2.1.3." + index1 + "." + index2, 4, SNMPBase.datatypes.integer));

            return sendSNMP(request);
        }
        public bool deleteVlan(int tag)
        {
            int untaggedindex = getVlanIndexID(tag, false);
            int taggedindex = getVlanIndexID(tag, true);
            if (untaggedindex == -1 || taggedindex == -1)
                return false;

            bool result = false;

            //remove the untagged to tagged mapping
            result = sendSNMP("1.3.6.1.2.1.31.1.2.1.3." + untaggedindex + "." + taggedindex, 6);
            if (result == false)
            {
                return false;
            }

            result = sendSNMP("1.3.6.1.4.1.1916.1.2.3.1.1.4." + taggedindex, 6);
            if (result == false)
            {
                return false;
            }

            result = sendSNMP("1.3.6.1.4.1.1916.1.2.1.2.1.6." + untaggedindex, 6);
            if (result == false)
            {
                return false;
            }
            return true;
        }

        public bool addPortToVlan(int tag, int ifIndex, bool isTagged)
        {

            //get the slot and port info for the ifIndex
            //string slotdata = getSNMP("1.3.6.1.2.1.31.1.1.1.1." + ifIndex, SNMPBase.datatypes.str);
            //int slot = Convert.ToInt32(slotdata.Substring(0, slotdata.IndexOf("/")));
            //int port = Convert.ToInt32(slotdata.Substring(slotdata.IndexOf("/") + 1));

            //Get the Vlan's Index ID
            int vlanIndex = getVlanIndexID(tag, isTagged);
            if (vlanIndex == -1)
                return false;
            //int tagged;
            //if (isTagged)
            //{
            //    tagged = 1;
            //}
            //else
            //{
            //    tagged = 2;
            //}

            //1.3.6.1.4.1.1916.1.6.3.0 i 0 
            //1.3.6.1.2.1.31.1.2.1.3.22015.1002 i 4
            //undofailed = port already in another vlan
            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.6.3.0", 0, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.2.1.31.1.2.1.3." + vlanIndex.ToString() + "." + ifIndex, 4));

            return sendSNMP(request);
        }

        public bool addFirstPorttoVlan(int tag, int ifIndex, bool isTagged, string vlanName)
        {
            //Extreme 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 removePortFromVlan(int tag, int ifIndex)
        {

            //Get the Vlan's Index ID
            int vlanIndex = getVlanIndexID(tag, false);
            if (vlanIndex == -1)
                return false;

            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.6.3.0", 0, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.2.1.31.1.2.1.3." + vlanIndex.ToString() + "." + ifIndex, 6, SNMPBase.datatypes.integer));

            return sendSNMP(request);
        }
 public bool? isPortInVlan(int tag, int ifIndex, bool tagged)
        {
            string slotdata;
            if (getSNMP("1.3.6.1.2.1.31.1.1.1.1." + ifIndex, SNMPBase.datatypes.str, out slotdata) == false)
                return null;

            int slot = Convert.ToInt32(slotdata.Substring(0, slotdata.IndexOf("\\")));
            int port = Convert.ToInt32(slotdata.Substring(slotdata.IndexOf("\\") + 1));

            Byte[] vlanMembers;
            if (getVlanMembers(tag, slot, tagged, out vlanMembers) == false)
                return null;

            return isPortMember(port, vlanMembers);

        }

        public Raw_VlanMemberCollection GetVlanMembers(int tag)
        {
            Raw_VlanMemberCollection data = new Raw_VlanMemberCollection();

            //get the number of slots 
            //int slots = Convert.ToInt32(getSNMP("1.3.6.1.4.1.1916.1.1.2.1.0", SNMPBase.datatypes.integer));

            NetworkPortCollection Ports = getPorts(false);
            int slots = GetNumberofSlots(Ports);

            // we have to process vlan memberships for each slot
            for (int slot = 1; slot <= slots; slot++)
            {
                //Get Tagged vlan members for slot
                Byte[] vlanMembers;
                if (getVlanMembers(tag, slot, true, out vlanMembers) == false)
                {
                    data.isErrorState = true;
                    return data;
                }

                ArrayList members = GetMemberPorts(vlanMembers); //Get a list of each port number based on mask


                foreach (int p in members)
                {
                    NetworkPort port = Ports.Find(o => o.slotNumber == slot && o.portNumber == p);
                    if (port != null) //we found our port lets update the membership
                    {
                        Raw_VlanMember member = new Raw_VlanMember();
                        member.isTagged = true;
                        member.tag = tag;
                        member.port = port.portNumber;
                        member.slot = port.slotNumber;
                        member.PortifIndex = port.ifIndex;
                        data.Add(member);
                    }
                }

                //Get un-Tagged vlan members for slot
                if (getVlanMembers(tag, slot, false, out vlanMembers) == false)
                {
                    data.isErrorState = true;
                    return data;
                }

                members = GetMemberPorts(vlanMembers); //Get a list of each port number based on mask
                //Ports = getPorts();

                foreach (int p in members)
                {
                    NetworkPort port = Ports.Find(o => o.slotNumber == slot && o.portNumber == p);
                    if (port != null) //we found our port lets update the membership
                    {
                        Raw_VlanMember member = new Raw_VlanMember();
                        member.isTagged = false;
                        member.tag = tag;
                        member.port = port.portNumber;
                        member.slot = port.slotNumber;
                        member.PortifIndex = port.ifIndex;
                        data.Add(member);
                    }
                }
            }
            return data;
        }
        private int GetNumberofSlots(NetworkPortCollection ports)
        {
            int maxslot = 1; // start off with 1 slot

            foreach (NetworkPort p in ports)
            {
                if (p.slotNumber > maxslot)
                    maxslot = p.slotNumber;
            }
            return maxslot;
        }

        public VlanCollection getVlans()
        {
            VlanCollection Vlans = new VlanCollection();

            //Get All the Vlans
            SNMPDataCollection data = walk("1.3.6.1.4.1.1916.1.2.1.2.1.10");
            if (data.isErrorState == true)
            {
                Vlans.isErrorState = true;
                return Vlans;
            }
            foreach (SNMPData obj in data)
            {
                string vlanTag = obj.value.ToString(); //each value will be a vlan
                string oid = obj.oid;
                int ifIndex = Convert.ToInt32(oid.Replace("1.3.6.1.4.1.1916.1.2.1.2.1.10.", string.Empty));

                //Will include 4095 which is the Management Vlan
                Vlan vlan = new Vlan();
                vlan.tag = Convert.ToInt32(vlanTag);
                vlan.ifIndex = Convert.ToInt32(ifIndex);
                vlan.name = getVlanName(vlan.tag);
                Vlans.Add(vlan);
            }

            return Vlans;
        }

        public NetworkPortCollection getPorts()
        {
            return getPorts(false);
        }

        public NetworkPortCollection getPorts(bool getPortStatus)
        {
            NetworkPortCollection Ports = new NetworkPortCollection();
            //Populate ports 
            SNMPDataCollection data = walk("1.3.6.1.2.1.31.1.1.1.17");
            if (data.isErrorState == true)
            {
                Ports.isErrorState = true;
                return Ports;
            }
            foreach (SNMPData obj in data)
            {
                //the port enumeration also returns VLan ifIndex and Mgmt port IfIndex
                //We can use 1.3.6.1.2.1.31.1.1.1.17 to see if a connector is present (is it a real port)

                if (obj.value.ToString() == "1") //connector is present
                {
                    int ifIndex = Convert.ToInt32(obj.oid.ToString().Substring(obj.oid.ToString().LastIndexOf(".") + 1));
                    int port = ifIndex % 1000;
                    int slot = (ifIndex - port) / 1000;

                    if (slot == 0) // if it was slot 0 set it to slot 1
                    {
                        slot = 1;
                    }

                    //Get the ports description
                    string description;
                    getSNMP("1.3.6.1.2.1.31.1.1.1.1." + ifIndex, SNMPBase.datatypes.str, out description);
                    if (description.ToLower() != "mgmt" && description.ToLower() != "management" && description.ToLower() != "management port") //we dont want to add the management ports
                    {
                        Ports.Add(new NetworkPort(ifIndex, slot, port));
                    }
                }
            }

            //Get Ports information
            foreach (NetworkPort port in Ports)
            {
                port.name = getPortDescription(port.ifIndex);
                if (getPortStatus)
                {
                    port.adminStatus = getPortAdminStatus(port.ifIndex);
                    port.operationStatus = getPortOperationStatus(port.ifIndex);
                }
            }
            return Ports;
        }
 /// 
        /// Query switch for member array of a given Vlan, slot and tag
        /// 
        /// 
        /// 
        /// 
        /// Extreme Vlan member array
        private bool getVlanMembers(int tag, int slot, bool isTagged, out Byte[] members)
        {
            members = new Byte[0];
            //Get the Vlan's Index ID
            int vlanIndex = getVlanIndexID(tag, false);
            if (vlanIndex == -1)
                return true; //Vlan was not found on switch

            int tagged;
            if (isTagged)
                tagged = 1;
            else
                tagged = 2;


            return getSNMP("1.3.6.1.4.1.1916.1.2.6.1.1." + tagged + "." + vlanIndex + "." + slot, out members);
        }

        /// 
        /// Process Byte Array to determine member ports
        /// 
        /// 
        /// Returns an array for port numbers for a MemberByteArray
        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 + 1 + bytecoute * 8;
                            members.Add(portNumber); //Add the portnumber to our returned list
                        }
                    }
                    bytecoute++;
                }
            }
            return members;
        }

        private int getVlanIndexID(int tag, bool tagged)
        {
            int untaggedindex = -1;
            int taggedindex = -1;
            //walk to get the vlans
            SNMPDataCollection data = walk("1.3.6.1.4.1.1916.1.2.1.2.1.10");
            if (data.isErrorState == true) 
                return -1;

            foreach (SNMPData item in data)
            {
                if (Convert.ToInt32(item.value) == tag)
                {
                    untaggedindex = Convert.ToInt32(item.oid.Replace("1.3.6.1.4.1.1916.1.2.1.2.1.10.", ""));
                    break;
                }
            }

            if (untaggedindex == -1)
                return -1;


            data = walk("1.3.6.1.4.1.1916.1.2.7.1.1.2." + untaggedindex);
            if (data.isErrorState == true)
                return -1;

            foreach (SNMPData item in data)
            {
                taggedindex = Convert.ToInt32(item.value);
                break;
            }

            if (tagged)
                return taggedindex;
            else
                return untaggedindex;
        }

        private static bool isPortMember(int portnumber, Byte[] membershipstream)
        {
            //Determine the port number we are working with for the given slot
            //Mod by 1000 to remove slot number; set remainder to portnumber
            portnumber %= 1000;

            Byte[] PORTMASKARRAY = { 128, 64, 32, 16, 8, 4, 2, 1 };
            return (membershipstream[(portnumber - 1) / 8] & PORTMASKARRAY[(portnumber - 1) % 8]) != 0;
        }

        /// 
        /// Extreme Byte Stream generation, used for modifing port membership in Vlan
        /// 
        /// portnumber to add/remove from vlan
        /// 
        private Byte[] ReneratePortByteStream(int portnumber, int MAXPORTSPERSLOT)
        {
            //Determine the port number we are working with for the given slot
            //Mod by 1000 to remove slot number; set remainder to portnumber
            //portnumber %= 1000;


            Byte[] holdingByte = null;

            //Create an Array to hold the changing value
            int bytesNeeded = MAXPORTSPERSLOT / 8 + (MAXPORTSPERSLOT % 8 <= 0 ? 0 : 1);
            holdingByte = new byte[bytesNeeded];

            //Determin which byte we are working with
            int byteposition = portnumber / 8;

            //Mod to find the bit we are working with 
            int maskindex = (portnumber - 1) % 8;

            //Set the value in our Holding array for the corisponding bit
            holdingByte[byteposition] |= PORTMASKARRAY[maskindex];

            return holdingByte;
        }

        private int getAvailableIndex()
        {
            string data;
            if (getSNMP("1.3.6.1.4.1.1916.1.2.2.1.0", SNMPBase.datatypes.integer, out data) == false)
                return -1;

            return Convert.ToInt32(data);
        }


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

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

Using C# to manage an Extreme XOS based switch via SNMP

This is to provide an example of a plug-in I wrote for the Green Monster System to manage an Extreme Networks XOS based switch.  This includes devices like the 350, 450 and BD10k and the like.

Most of these commands were determined via many hours with network sniffer as the MIBs do not expose the OIDs used here.

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)
        {
            // Query to get the next available index for this switch
            int index = getAvailableIndex();
            if (index == -1)
                return false;

            // Set 1.3.6.1.4.1.1916.1.2.1.2.1.1.Index value = index type=integer
            // Set 1.3.6.1.4.1.1916.1.2.1.2.1.2.index value = Vlan Name Type=String
            // Set 3.6.1.4.1.1916.1.2.1.2.1.10.index value=vlantag Type=integer
            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.1." + index, index, SNMPBase.datatypes.integer));

            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.2." + index, name, SNMPBase.datatypes.str));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.1.2.1.10." + index, tag, SNMPBase.datatypes.integer));
            return sendSNMP(request);
        }
        public bool deleteVlan(int tag)
        {
            int index = getVlanIndexID(tag);
            if (index == -1)
                return false;

            return sendSNMP("1.3.6.1.4.1.1916.1.2.1.2.1.6." + index, 6);
        }

        public bool addPortToVlan(int tag, int ifIndex, bool isTagged)
        {

            //get the slot and port info for the ifIndex :
            string slotdata;
            if (getSNMP("1.3.6.1.2.1.31.1.1.1.1." + ifIndex, SNMPBase.datatypes.str, out slotdata) == false)
                return false;

            if (slotdata.IndexOf(":") == -1)
                return false;

            int slot = Convert.ToInt32(slotdata.Substring(0, slotdata.IndexOf(":")));
            int port = Convert.ToInt32(slotdata.Substring(slotdata.IndexOf(":") + 1));

            //Get the Vlan's Index ID
            int vlanIndex = getVlanIndexID(tag);

            if (vlanIndex == -1)
                return false;

            int tagged;
            if (isTagged)
                tagged = 1;
            else
                tagged = 2;

            // Create the byte array that will hold the bits for the port we are going to modify in the vlan
            int maxportsperslot = getMaxPortsperSlot();
            if (maxportsperslot == -1)
                return false;
            byte[] changearray = GeneratePortByteStream(port, maxportsperslot);

            // Set 1.3.6.1.4.1.1916.1.2.6.2.1.1.. x 00000000000040 (bit mask of ports to add)
            // set 1.3.6.1.4.1.1916.1.2.6.2.1.2..Type=integer Value =1 or 2 (1=tagged 2=untagged)
            // Set 1.3.6.1.4.1.1916.1.2.6.2.1.3.. Type=integer Value=4 

            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.6.2.1.1." + vlanIndex.ToString() + "." + slot.ToString(), changearray, SNMPBase.datatypes.str));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.6.2.1.2." + vlanIndex.ToString() + "." + slot.ToString(), tagged, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.6.2.1.3." + vlanIndex.ToString() + "." + slot.ToString(), 4, SNMPBase.datatypes.integer));
            return sendSNMP(request);
        }

        public bool addFirstPorttoVlan(int tag, int ifIndex, bool isTagged, string vlanName)
        {
            //Extreme 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 removePortFromVlan(int tag, int ifIndex)
        {
            //get the slot and port info for the ifIndex
            string slotdata;
            if (getSNMP("1.3.6.1.2.1.31.1.1.1.1." + ifIndex, SNMPBase.datatypes.str, out slotdata) == false)
                return false;

            int slot = Convert.ToInt32(slotdata.Substring(0, slotdata.IndexOf(":")));
            int port = Convert.ToInt32(slotdata.Substring(slotdata.IndexOf(":") + 1));

            //Get the Vlan's Index ID
            int vlanIndex = getVlanIndexID(tag);

            if (vlanIndex == -1)
                return false;

            //Create the byte array that will hold the bits for the port we are going to modify in the vlan
            int maxportsperslot = getMaxPortsperSlot();
            if (maxportsperslot == -1)
                return false;
            byte[] changearray = GeneratePortByteStream(port, maxportsperslot);

            //Set 1.3.6.1.4.1.1916.1.2.6.2.1.1.. x 00000000000040 (bit mask of ports to remove)
            //set 1.3.6.1.4.1.1916.1.2.6.2.1.2..Type=integer Value =3
            //Set 1.3.6.1.4.1.1916.1.2.6.2.1.3.. Type=integer Value=4

            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.6.2.1.1." + vlanIndex.ToString() + "." + slot.ToString(), changearray, SNMPBase.datatypes.str));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.6.2.1.2." + vlanIndex.ToString() + "." + slot.ToString(), 3, SNMPBase.datatypes.integer));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.6.2.1.3." + vlanIndex.ToString() + "." + slot.ToString(), 4, SNMPBase.datatypes.integer));
            return sendSNMP(request);
        }

       public bool? isPortInVlan(int tag, int ifIndex, bool tagged)
        {
            string slotdata;
            if (getSNMP("1.3.6.1.2.1.31.1.1.1.1." + ifIndex, SNMPBase.datatypes.str, out slotdata) == false)
                return null;

            int slot = Convert.ToInt32(slotdata.Substring(0, slotdata.IndexOf(":") + 1));
            int port = Convert.ToInt32(slotdata.Substring(slotdata.IndexOf(":") + 1));

            Byte[] vlanMembers;
            if (getVlanMembers(tag, slot, tagged, out vlanMembers) == false)
                return null;

            return isPortMember(port, vlanMembers);

        }

        public Raw_VlanMemberCollection GetVlanMembers(int tag)
        {
            Raw_VlanMemberCollection data = new Raw_VlanMemberCollection();

            //get the number of slots 
            string getData;
            if (getSNMP("1.3.6.1.4.1.1916.1.1.2.1.0", SNMPBase.datatypes.integer, out getData) == false)
            {
                data.isErrorState = true;
                return data;
            }
            int slots = -1;
            if (Int32.TryParse(getData, out slots) == false)
            {
                System.Threading.Thread.Sleep(1000);
                //Failed to get valid data from switch.  Try again
                if (getSNMP("1.3.6.1.4.1.1916.1.1.2.1.0", SNMPBase.datatypes.integer, out getData) == false)
                {
                    data.isErrorState = true;
                    return data;
                }
                if (Int32.TryParse(getData, out slots) == false)
                {
                    throw new TimeoutException("Failed to contact Switch IP " + this.DeviceIP + " via SNMP, the switch might be down or busy.  Try again later or contact the admin");
                }
            }
            if (slots == -1)
                throw new ArgumentOutOfRangeException("Failed to lookup correct slot information for device at IP" + this.DeviceIP);

            int vlanIndex = getVlanIndexID(tag);
            if (vlanIndex == -1)
            {
               // data.isErrorState = true;
                return data;
            }

            NetworkPortCollection Ports = getPorts();
            // we have to process vlan memberships for each slot
            for (int slot = 1; slot <= slots; slot++)
            {
                //Get Tagged vlan members for slot
                Byte[] vlanMembers;
                if (getVlanMembers(tag, slot, true, out vlanMembers) == false)
                {
                    data.isErrorState = true;
                    return data;
                }

                ArrayList members = GetMemberPorts(vlanMembers); //Get a list of each port number based on mask


                foreach (int p in members)
                {
                    NetworkPort port = Ports.Find(delegate(NetworkPort o) { return o.slotNumber == slot && o.portNumber == p; });
                    if (port != null) //we found our port lets update the membership
                    {
                        Raw_VlanMember member = new Raw_VlanMember();
                        member.isTagged = true;
                        member.tag = tag;
                        member.port = port.portNumber;
                        member.slot = port.slotNumber;
                        member.PortifIndex = port.ifIndex;
                        member.VlanifIndex = vlanIndex;
                        data.Add(member);
                    }
                }

                //Get un-Tagged vlan members for slot
                if (getVlanMembers(tag, slot, false, out vlanMembers) == false)
                {
                    data.isErrorState = true;
                    return data;
                }

                members = GetMemberPorts(vlanMembers); //Get a list of each port number based on mask
                // Ports = getPorts();

                foreach (int p in members)
                {
                    NetworkPort port = Ports.Find(delegate(NetworkPort o) { return o.slotNumber == slot && o.portNumber == p; });
                    if (port != null) //we found our port lets update the membership
                    {
                        Raw_VlanMember member = new Raw_VlanMember();
                        member.isTagged = false;
                        member.tag = tag;
                        member.port = port.portNumber;
                        member.slot = port.slotNumber;
                        member.PortifIndex = port.ifIndex;
                        member.VlanifIndex = vlanIndex;
                        data.Add(member);
                    }
                }
            }
            return data;
        }
        public VlanCollection getVlans()
        {
            VlanCollection Vlans = new VlanCollection();

            //Get All the Vlans
            SNMPDataCollection data = walk("1.3.6.1.4.1.1916.1.2.1.2.1.10");
            if (data.isErrorState == true)
            {
                Vlans.isErrorState = true;
                return Vlans;
            }
            foreach (SNMPData obj in data)
            {
                string vlanTag = obj.value.ToString(); //each value will be a vlan
                string oid = obj.oid;
                int ifIndex = Convert.ToInt32(oid.Replace("1.3.6.1.4.1.1916.1.2.1.2.1.10.", string.Empty));

                //Will include 4095 which is the Management Vlan
                Vlan vlan = new Vlan();
                vlan.tag = Convert.ToInt32(vlanTag);
                vlan.ifIndex = Convert.ToInt32(ifIndex);
                vlan.name = getVlanName(vlan.tag);
                Vlans.Add(vlan);
            }

            return Vlans;
        }
      public bool setVlanIPAddress(int vlanTag, string ipAddress, string NetworkMask)
        {
            int vlanIfIndex = getVlanIndexID(vlanTag);
            if (vlanIfIndex == -1)
                return false; //unable to find vlan index

            if (ipAddress == string.Empty)
                return clearVlanIPaddress(vlanIfIndex); // doing a cleanup


            if (NetworkMask == string.Empty)
                return false; // dont allow a null network mask

            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.4.1.1.1." + vlanIfIndex, ipAddress, SNMPBase.datatypes.ipAddress));
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.4.1.1.2." + vlanIfIndex, NetworkMask, SNMPBase.datatypes.ipAddress));
            sendSNMP(request);

            request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.4.1.1.3." + vlanIfIndex, 1, SNMPBase.datatypes.integer)); //activate the IP
            return sendSNMP(request);

        }

        public string getVlanIPAddress(int vlanTag)
        {
            int vlanIfIndex = getVlanIndexID(vlanTag);
            if (vlanIfIndex == -1)
                return string.Empty; //unable to find vlan index
            string result;
            getSNMP("1.3.6.1.4.1.1916.1.2.4.1.1.1." + vlanIfIndex, SNMPBase.datatypes.ipAddress, out result);
            return result;
        }
        public string getVlanNetworkMask(int vlanTag)
        {
            int vlanIfIndex = getVlanIndexID(vlanTag);
            if (vlanIfIndex == -1)
                return string.Empty; //unable to find vlan index
            string result;
            getSNMP("1.3.6.1.4.1.1916.1.2.4.1.1.2." + vlanIfIndex, SNMPBase.datatypes.ipAddress, out result);
            return result;
        }
        public bool setVLanIPForward(int vlanTag, bool Enabled)
        {
            if (getVlanIPAddress(vlanTag) == string.Empty)
                return false; //no ip Set

            int vlanIfIndex = getVlanIndexID(vlanTag);
            if (vlanIfIndex == -1)
                return false; //unable to find vlan index

            int value = Enabled == true ? 1 : 2; // 1 = enabled, 2 = disabled

            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.4.1.1.4." + vlanIfIndex, value, SNMPBase.datatypes.integer));
            return sendSNMP(request);
        }
        public bool? getVlanIPForward(int vlanTag)
        {
            if (getVlanIPAddress(vlanTag) == string.Empty)
                return false; //no ip Set
            int vlanIfIndex = getVlanIndexID(vlanTag);
            if (vlanIfIndex == -1)
                return false; //unable to find vlan index

            string value;
            if (getSNMP("1.3.6.1.4.1.1916.1.2.4.1.1.4." + vlanIfIndex, SNMPBase.datatypes.integer, out value) == false)
                return null;
            if (value == "2")
                return false;
            else
                return true;

        }

        private bool clearVlanIPaddress(int ifIndex)
        {
            //check to see if a ip is set
            string state;
            if (getSNMP("1.3.6.1.4.1.1916.1.2.4.1.1.3." + ifIndex, SNMPBase.datatypes.integer, out state) == false)
                return false;

            if (state == string.Empty) //no ip set
                return true;

            SNMPDataCollection request = new SNMPDataCollection();
            request.Add(new SNMPData("1.3.6.1.4.1.1916.1.2.4.1.1.3." + ifIndex, 6, SNMPBase.datatypes.integer)); //delete the IP Address
            return sendSNMP(request);
        }
#region "internal methods"

        /// 
        /// Query switch for member array of a given Vlan, slot and tag
        /// 
        /// 
        /// 
        /// 
        /// Extreme Vlan member array
        private bool getVlanMembers(int tag, int slot, bool isTagged, out Byte[] members)
        {
            //Get the Vlan's Index ID
            members = new Byte[0];
            int vlanIndex = getVlanIndexID(tag);
            if (vlanIndex == -1)
                return false;

            int tagged;
            if (isTagged)
                tagged = 1;
            else
                tagged = 2;


            return getSNMP("1.3.6.1.4.1.1916.1.2.6.1.1." + tagged + "." + vlanIndex + "." + slot, out members);

        }

        /// 
        /// Process Byte Array to determine member ports
        /// 
        /// 
        /// Returns an array for port numbers for a MemberByteArray
        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 + 1 + bytecoute * 8;
                            members.Add(portNumber); // Add the portnumber to our returned list
                        }
                    }
                    bytecoute++;
                }
            }
            return members;
        }

        private int getVlanIndexID(int tag)
        {
            bool triedagain = false;

        tryagain: ;
            //walk to get the vlans
            SNMPDataCollection data = walk("1.3.6.1.4.1.1916.1.2.1.2.1.10");
            if (data.isErrorState == true)
                return -1;

            foreach (SNMPData item in data)
            {
                if (Convert.ToInt32(item.value) == tag)
                    return Convert.ToInt32(item.oid.Replace("1.3.6.1.4.1.1916.1.2.1.2.1.10.", ""));
            }
            if (triedagain == false)
            {
                triedagain = true;
                System.Threading.Thread.Sleep(100);
                goto tryagain;
            }
            return -1; //Could not find the tag
        }

        private static bool isPortMember(int portnumber, Byte[] membershipstream)
        {
            //Determine the port number we are working with for the given slot
            //Mod by 1000 to remove slot number; set remainder to portnumber
            portnumber %= 1000;

            Byte[] PORTMASKARRAY = { 128, 64, 32, 16, 8, 4, 2, 1 };
            return (membershipstream[(portnumber - 1) / 8] & PORTMASKARRAY[(portnumber - 1) % 8]) != 0;
        }

        /// 
        /// Extreme Byte Stream generation, used for modifing port membership in Vlan
        /// 
        /// portnumber to add/remove from vlan
        /// 
        private Byte[] GeneratePortByteStream(int portnumber, int MAXPORTSPERSLOT)
        {
            //Determine the port number we are working with for the given slot
            //Mod by 1000 to remove slot number; set remainder to portnumber
            //portnumber %= 1000;


            Byte[] holdingByte = null;

            //Create an Array to hold the changing value
            int bytesNeeded = MAXPORTSPERSLOT / 8 + (MAXPORTSPERSLOT % 8 <= 0 ? 0 : 1);
            holdingByte = new byte[bytesNeeded];

            //Determin which byte we are working with
            int byteposition = (portnumber - 1) / 8;

            //Mod to find the bit we are working with 
            int maskindex = (portnumber - 1) % 8;

            //Set the value in our Holding array for the corisponding bit
            holdingByte[byteposition] |= PORTMASKARRAY[maskindex];

            return holdingByte;
        }

        private int getMaxPortsperSlot()
        {
            //Get Max ports per Slot
            string data;
            if (getSNMP("1.3.6.1.4.1.1916.1.1.2.3.0", SNMPBase.datatypes.integer, out data) == false)
                return -1;

            return Convert.ToInt32(data);
        }

        private int getAvailableIndex()
        {
            string data;
            if (getSNMP("1.3.6.1.4.1.1916.1.2.2.1.0", SNMPBase.datatypes.integer, out data) == false)
                return -1;

            return Convert.ToInt32(data);
        }

        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();
        }
        #endregion

    }
}

Post 1: Building a cross platform network switch automation system

Note: I have had this info in a pending publish state for a while and decided to finally post it. 


When I was a team member at the Enterprise Engineer Center (http://www.microsoft.com/en-us/eec/default.aspx) we use a mix of network equipment (and Power PDUs, KVM, Servers and SAN).  The EEC hosts customer “engagements” to test/validate scale, proof of concept and features.  The facility has 7 customer labs and security is a number 1 priority. The EEC has multiple levels of security to isolate customer environments from each other, our team systems, and the Microsoft corporate network.  Vlans are used extensively as part of the isolation system and as part of testing customer scenarios.  Some test environments may only have 1 Vlan others may have 25.  Vlans are created and deleted as required for the scenarios being tested. As “the networking guy” I was called to action regularly to help resolve connectivity issues with Vlans that spanned multiple switches.  Many times the issues were caused by a single interface missing its Vlan configuration (tagged or untagged).   While the fix for issues was very easy finding which interface was incorrectly configured proved to be very time consuming. 

To increase the complexity the EEC uses a mix of network switch vendors depending on our partnership and features offered by each.  We also have a large variety of server equipment from multiple partners. These servers can be pre-release systems or a single system that fits a custom need.

As the EEC started its major remodel in 2008 we viewed this as a great time to improve our systems and processes.

In 2008 I started work on a project codenamed Green Monster (GM).  The goals of Green Monster were

1. Reduce the manual process required to perform network vlan and Layer 3 changes by creating automation framework
2. Support a diverse list of equipment manufacturers (network, power, kvm, servers)
3. Create a database of equipment inventory to replace excel spreadsheets
4. Create a database of network and power port to server mappings
5. Provide an automated system to power systems on/off
6. Create a near zero touch OS deployment environment for Engagement build out/setup
7. Abstract hardware vendor and network design from users (UI or script interface)


Development of Green Monster was to be done as a side project.  I was the PM, Dev and for the most part the tester.  Many of my teammates helped with feature feedback, DB design ideas and testing. They also provided a large list of features and ideas for future versions.

Green Monster consists of a WCF Service that performs all the automation logic, DB interaction and device integration. The frontend is a C# UI that consumes the WCF service.  OS imaging was done with WDS and some in-house scripts written by a co-worker.

I will be posting information about specific features and provide code snips on how I interact with devices over the network.

Wednesday, July 27, 2011

Windows Server 2008 Hyper-V Geographically Dispersed Cluster with IBM XIV Storage iSCSI

Here is a paper that I worked on at my team at Microsoft. The Enterprise Engineering Center (http://www.microsoft.com/eec) has a IBM XIV array that we used with the other array on campus.

Windows Server 2008 Hyper-V Geographically Dispersed Cluster with IBM XIV Storage iSCSI

You can find more info on the Tunnel used in this whitepaper at http://www.mikepoulson.com/2011/06/l2tpv3-performance-tweaks-for-hyperv.html

Saturday, June 18, 2011

Managing lots of Cisco consoles from one location

Repost from old blog

Any who. The issue: Lets say you have 16 or so Cisco devices (extreme works also) that connect to various parts of your network. Now you want to be able to manage these devices remotely but not make a huge security hole using Vlans and attempting to keep it all secure with ACLs.

So the easy way is to do all the management via the console port. No ACLs to worry about and easier to secure.

So I have 16+ Cisco devices from Routers to switches (2950s, 3550s, 2621s, 2651s, 3750s, 4912s and even an AS5300) all in my lab. So with all those in my lab I got myself a DIGI portserver TS 16 Rack mount device (we use them for kernel debugging also). With a special digi to cisco cable (yes I will give you the pin-outs if you want them) I connect each cisco's console port to the digi and then the DIGI's Ethernet port to my "management network". The management network is where my management workstation lives.

The digi device will let you telnet or ssh (SSH is better) into it. Then from there connect to each of its ports (using the connect command). Now where the fun comes in is how to setup the DIGI to talk to the cisco. Then create a menu so you dont alway have to know the port number each device is connected to.

So below are the steps to allow you to connect the DIGI to the cisco (once you have the cable).
1.Make sure your device is up to date. I am using 82000685_E.bin and 82000684_L.bin
2.Know your port numbers (we are going to use ports 1-16)
3.Set the port type to printer (set ports range=1-16 dev=prn)
4.set the ip on your digi (set config dhcp=off ip= submask=)

At this point you should be able to use "connect 1" and connect to port 1. A few hits of the enter key and it should show you the cisco console.

Now we need to secure the device a little more by turning off things that are not needed. This will leave only telnet and ssh on (I would turn off telnet also but if you dont have an ssh client then it is kinda hard to use).
1.set secureaccess http=off snmp=off rlogin=off rsh=off https=off realport=off securerealport=off
2.set secureaccess reversessh=off securesockets=off reversetcp=off reversetelnet=off

We need to make our menu before we assign a user to use it. This will be an example of ports 1-3 with a title bar
1.set menu range=1 t1="Cisco management" t2="Make sure you save!" name=menu1
2.set menu range=1 m1="cisco 1" c1="connect 1"
3.set menu range=1 m2="cisco 2" c2="connect 2"
4.set menu range=1 m3="cisco 3" c3="connect 3"

Now lets make a user that we will connect with to see our menu
1.set user name= defaultaccess=menu menu=1

Set the password for our new digi user
1.newpass name=

Now a little know tip. When use the default escape char with digi it will leave the port open and not let you reconnect until you do a kill tty= (you can see the ttys by running the 'who' command). But if you use the escapekill command (default is a . (that is a period)) then it will close the tty when you escape. So the default escape command is "+]" . Now add a period after that and hit enter and you will kill the connection not just disconnect so a "+].". Now you press the control and ] key in one key stroke then the period in another.

Now you should be able to telnet or ssh into your ip and get a menu. Press 1 to connect cisco 1, 2 to connect to cisco 2, and 3 to connect to cisco 3.

How great!

Regular Expressions and IP addresses (ipv4 and IPv6)

Repost from old blog

Over the last year or so I have been writing automation that uses IPv4 and IPv6 addresses. In the beginning I had to dig up and make some regular expressions for verifying that a given value was a valid IPv4 or IPv6 address.

The ones I came up with are (in VB.net)

Const strIPv4Pattern as string = "\A(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\z" 'IPv4 Address Regex pattern (x.x.x.x)

Const strIPv6Pattern as string = "\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\z"

Const strIPv6Pattern_HEXCompressed as string = "\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\z"

Const StrIPv6Pattern_6Hex4Dec as string = "\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\z"

Const StrIPv6Pattern_Hex4DecCompressed as string = "\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\z"

Now because an IPv6 address can take a few forms we have 4 different expressions for IPv6. If someone finds a bug in one of these please let me know. Because RegExp is something that I am not good at.

Hope these will help some one.

IPv6 6over4 tunnels with Windows and Cisco

Repost from old blog
A few years ago I began working with Art Shelest here at Microsoft to get Native IPv6 running in my lab.  After a few weeks we had it up and running. 
We had to work with MSIT (was known as ITG at the time) to get a 6over4 tunnel setup so that we could connect to the 6bone even though my upstream routers did not support IPv6 (still don't at this time).  Once the tunnel was setup on the ITG Router we ran a command on my Windows IPv6 Router in my lab and it was up and running. 
We run our entire lab IPv6 network on Windows Routers.  We use Windows Server 2003 but you could use Windows XP Pro if you wanted.  Unlike RRAS the IPv6 routing stack is included in Windows XP.  And after Windows XP SP1 this stack was fully supported by Microsoft support.  So if you follow the steps at http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sag_ip_v6_imp_lab_node.mspx you can get your internal test network setup.
Now to create a 6over4 tunnel to another router you simply run the below commands from a cmd prompt on your main IPv6  router
  1. netsh
  2. int ipv6
  3. add v6v4tunnel interface="V6v4 Tunnel" localaddress=<local ipv4 address> remoteaddress=<remote ipv4 address>
  4. set interface "v6v4 Tunnel for=en
  5. add address int="v6v4 tunnel" address=<IPv6 address from provider>
  6. add route ::/0 "v6v4 tunnel" <remote IPv6 address> publish=yes
Key things to note with the above
  • The Local IPv4 address is the IP address that the tunnel is going to use to talk to the Upstream V6 Router (With my example below it would be 1.1.1.1). 
  • The Remote IPv4 Address is the IP address of the upstream V6 router (with my example below it would be 2.2.2.1).
  • The IPv6 address from provider would be a IPv6 address that you get from your v6 provider (with my example below it would be 3ffe:ffee:100:2::2)
  • The Remote IPv6 address is the IPv6 address of the upstream IPv6 router (with my example below it would be 3FFE:FFEE:100:2::1)
The Cisco side of the config looks like this
interface Tunnel1
 description v6in4 tunnel to  lab 1.1.1.1/3FFE:FFEE:100:2::2
 no ip address
 ipv6 address 3FFE:FFEE:100:2::1/64
 tunnel source 2.2.2.1
 tunnel destination 1.1.1.1
 tunnel mode ipv6ip



Once the machines are all setup important things to know are "how do you back up your ipv6 configuration?" Well with netsh it could not be easier.
Simply run 'netsh int ipv6 dump > c:\ipv6backup.txt'  this will dump all the ipv6 config out to the txt file.  Now if the router was to ever go down you can run the command  'netsh exec c:\ipv6backup.txt'.   With these 2 commands it will backup and restore your ipv6 configuration..  You can also modify the backup command to be 'netsh dump > c:\netshbackup.txt' and it will back up 99% of all the settings for your network configuration.
If you would like to know more about how I have my IPv6 network setup please let me know.  Also I recommend the Microsoft Press Book Understanding IPv6 (http://www.microsoft.com/MSPress/books/4883.asp) ISBN: 0-7356-1245-5

How to speed up Queries to MicrosoftDNS with WMI

Repost from old blog

So there are many key things to remember when creating your WMI queries make them as specific as you can.

For example if you have ~5000 zones on your Microsoft DNS server and you are looking to see if a single record exists in one of those zones the wrong query could take 1 min+ to complete.

Why?

If you do a query like Select * from MicrosoftDNS_AType where ownername="www.mydomain.com" it is going to take a while. Because you did not specify where to look for this record it is going to look in the RootHints and in the DNS Cache also. So if you have a public DNS server that does recursive lookups it could have a few hundred thousand extra records.

So a better query would be Select TextRepresentation from MicrosoftDNS_AType where containername="mydomainname" and domainname="mydomain.com" and ownername=www.mydomain.com

You can use a vbscript like the one below to test your queries. This will show you the correct domainname and other settings to use in your query. You can remove the where clause to show all the data on the server.

The containername will be the name of the zone that holds the records that you want to query for (Ie mydomain.com). If you leave the containername empty it will also search through the DNS cache.

The domainname specifies the child folder (don’t know how else to describe it). So if you have www.user.mydomain.com the domainname is user.mydomain.com

Now the domainname will change depending on if there are sub domains to the subdomain (ie www from example above). So if www does not exist then the domainname is mydomain.com. And of course there are exceptions to this rule. If there ever was a child to the sub (you deleted www but left user.mydomain.com) then the domainname is user.mydomain.com. If you don’t want to attempt to do the logic around making sure you have the correct domainname you can omit it. But if you have a large number of records it could make it slow.

Like SQL the order of the statements in the query is also important.

If you know the full record info (hostname, TYPE, data) it is fastest to generate the text representation and query on that. You can do that by adding changing your query to something like:

Select * from MicrosoftDNS_AType where containername=”test.com” and domainname=”test.com” and TextRepresentation="test.com IN A 192.168.0.1"



on error resume next
servername = "."
domainname = "test.com"

recordtype = "A"

set dnsserver = Getobject("winmgmts:{Authenticationlevel=pktPrivacy}!\\" & servername & "\root\MicrosoftDNS")

query = "Select * from MicrosoftDNS_" & recordtype & "Type where containername=""" & domainname & """"
wscript.echo "Query=" & query

Set colItems = dnsserver.ExecQuery(query,,48)
if colitems.count <> 0 then
For Each objItem in colItems
Wscript.Echo "ContainerName: " & objItem.ContainerName
Wscript.Echo "DnsServerName: " & objItem.DnsServerName
Wscript.Echo "DomainName: " & objItem.DomainName
Wscript.Echo "OwnerName: " & objItem.OwnerName
Wscript.Echo "PrimaryName: " & objItem.PrimaryName
Wscript.Echo "RecordClass: " & objItem.RecordClass
Wscript.Echo "RecordData: " & objItem.RecordData
Wscript.Echo "TextRepresentation: " & objItem.TextRepresentation
Wscript.Echo "Timestamp: " & objItem.Timestamp
Wscript.Echo "TTL: " & objItem.TTL
Next
end if

L2TPv3 performance tweaks for HyperV GeoCluster Live Migration

L2TPv3 is a great feature for extending a Layer2 network across sites. This is very useful when you are using Live Migration with HyperV or when you want to pass traffic (at Layer 2) to a different location. 
 
Recently while working on a SAN GeoClustering test case we want to do a stretched VLan from one lab to another (in different buildings). This gets tricky because we (my team) don’t own or manage the network infrastructure between these buildings. Many companies will use MPLS/VPLS to create a VPN or VLL (Virtual Leased Line) between two sites. This can be expensive and a pain to get setup if you only need a link for a short period of time.
 
Stretched VLans are becoming more and more common as feature like Live Migration allow the moving of a system from one datacenter to another at the push of a button (well mouse clicks). 
 
The setup:
Sites: We were testing at labs that are about &frac14; of a mile apart from each other on opposite sides of Main Campus
 
The test network consisted for 4 vlans. These networks were duplicated at both sites
·         Public -- internet facing for request to HyperV hosted servers
·         Cluster – heartbeat network for Fail over Cluster
·         Live Migration – network to pass server state during live migration
·         Management – backend network to access remove desktop to servers and devices
 
Servers: We had 6 physical servers for the test (3 at each site). Each site had the same setup for servers
·         Server 1 – Host infrastructure systems (AD, DNS, DHCP, WDS)
·         Server 2 &3 – Fail over cluster hosts that would host the workload VMs
 
To interconnect the 4 vlans across buildings we uses the existing IPv4 infrastructure and 2 cisco routers. The building infrastructure offers > 1gbps in an out of each lab, so we connected with 1gig interfaces to uplinks. We also do not have visibility into MTU on building (intra and inter) infrastructure.
 
So down to what we found and what we changed:
Original Setup (poor performance): - config shown below
·         Single L2TPv3 Tunnel between sites
·         Lab facing interfaces were connected to switch that was a trunk port allowing our 4 VLans
          o   Switchport mode trunk
Original design findings:
·         Traffic passed (with 802.1q tags) correctly through tunnel
·         MAX bandwidth when coping files/Live Migration from site to site was 20-30mbps
·         Large amount of dropped packets in queue
·         CPU maxed at 100%
 
Tweaked design (best performance)
·         4 tunnels (one for each vlan) using sub interfaces
·         No change to switch trunk config
·         Modified hold-queue on each physical interface
·         Enabled MTU tuning on pseudowire-class (ip pmtu)
·         Enabled Don’t Fragment bit on pseudowire-class (ip dfbit set)
Tweaked design Findings:
·         Traffic passed correctly through tunnel
          o   Each VLan correctly mapped on either side
·         MAX bandwidth when coping files/Live Migration from site to site was ~800mbps
·         CPU would be around 40%
 
Original Config (each site was identical except swapped xconnect ip with interface ip address) – SLOW!
---
l2tp-class class1
authentication
password 0 123456789
!
pseudowire-class ethernet
encapsulation l2tpv3
protocol l2tpv3 class1
ip local interface GigabitEthernet0/1
!
interface GigabitEthernet0/0
no ip address
duplex full
speed auto
no cdp enable
xconnect 10.216.44.47 125 pw-class ethernet
!
interface GigabitEthernet0/1
ip address 10.197.251.215 255.255.255.240
duplex auto
speed auto
no cdp enable
!
ip route 0.0.0.0 0.0.0.0 10.197.251.209
!
no cdp run
!
End
 
Tweaked Design
--
l2tp-class class1
authentication
password 0 123456789
!
pseudowire-class ethernet
encapsulation l2tpv3
protocol l2tpv3 class1
ip local interface GigabitEthernet0/1
ip pmtu
ip dfbit set
!
interface GigabitEthernet0/0
no ip address
duplex full
speed auto
no cdp enable
hold-queue 2048 in
hold-queue 2048 out
!
interface GigabitEthernet0/0.2996
encapsulation dot1Q 2996
no cdp enable
xconnect 10.216.44.47 126 encapsulation l2tpv3 pw-class ethernet
!
interface GigabitEthernet0/0.2997
encapsulation dot1Q 2997
no cdp enable
xconnect 10.216.44.47 127 encapsulation l2tpv3 pw-class ethernet
!
interface GigabitEthernet0/0.2998
encapsulation dot1Q 2998
no cdp enable
xconnect 10.216.44.47 128 encapsulation l2tpv3 pw-class ethernet
!
interface GigabitEthernet0/0.2999
encapsulation dot1Q 2999
no cdp enable
xconnect 10.216.44.47 125 encapsulation l2tpv3 pw-class ethernet
!
interface GigabitEthernet0/1
ip address 10.197.251.215 255.255.255.240
duplex auto
speed auto
no cdp enable
hold-queue 2048 in
hold-queue 2048 out
!
ip route 0.0.0.0 0.0.0.0 10.197.251.209
!
no cdp run
!
 

Programmatically Controlling Pioneer Receivers and BluRay Players

I recently got a new Pioneer Elite SC-35 receiver (http://www.pioneerelectronics.com/PUSA/Products/HomeEntertainment/AV-Receivers/EliteReceivers/ci.SC-35.Kuro).  This receiver has an ethernet plug on the rear and is supported by the iPhone/iPOD app called iControlAV. 
While the receiver has a web interface called "Pioneer Web Control System" I wanted a way to control this receiver via script. The web interface has support for
  • Powering the receiver on/off
  • Changing the Volume including mute
  • Changing the Input (Zones 1-3)
  • Changing the "Listening Mode"
The iControlAV app for iPhone supports the same plus a few more options.
The iControlAV uses SSDP query to find the receiver. Which runs NU-OS 1.13.  You can Browse to http://<Receiver IP>/BasicDevice.xml to get the info on your device. 
My receiver has port 23 (telnet) open along with 80 and 8102 (referenced in BasicDevice.xml)
Basic process:
  • Send command as ASCII on telnet (23) or TCP/8102 (see your BasicDevice.xml)
  • Commands that check status or query the device begin with a ?
  • Commands that perform a command sometimes have parameters (input number) at begining, some at end
  • You can monitor the telnet window to see the "response" for each command sent.  This includes commands sent through IR remote or from the device its self.
Basic Commands (more commands to come in another post):
?P
Is Device powered ON?
PWR0 Device is ON
PWR1 Device is OFF
PF Power Device OFF
PO Power Device ON
?M  Is Zone MAIN muted
MUT1 Zone is NOT Muted
MUT0 Zone is Muted
MO  Mute MAIN zone
MF  unMute MAIN zone
?V Get Current Volume level
VOLxxx Current volume level, xxx is 000-200
VOL121 -20.0db
VOL081 -40.0db
XXXVL Set Volume Level to XXX (000 - 200)
001VL Set Volume Level to -80.0db
081VL Set Volume Level to -40.0db
?RGC Get inputs on device (i think)
RGC111001002 *Unknown*
?RGBxx Get inputs Name (related to above command), available inputs will change based on model
?RGB01 RGB010CD
?RGB02 RGB020TUNER
?RGB03 RGB030CD-R/TAPE
?F Get current input (use ?RGB to get name)
FN19 Input 19
FN15 Input 15
XXFN Set current input (XX = Input number)
XX Input number
19FN Set to input 19
15FN Set to input 15
?BP *UNKNOWN*
BPR1
?AP *UNKNOWN*
APR1
Example
Turn on device, set input to HDMI1 (19 in my case), and volume to -40db

PO

19FN

081VL

(Update: 7/17/2011)
I was able to find a doc that has all the commands (better than what I was able to determine). 
http://dl.dropbox.com/u/3275573/2010%20USA%20AVR%20RS-232C%20%26%20IP%20Commands%20for%20CI.pdf

10 Years from last post

 Well world!   After the last almost 10 years I have been up to a few things in life and work.  Most recently I was working at Microsoft on ...