Showing posts with label Programming. Show all posts
Showing posts with label Programming. 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

How to create differencing disk VM from template on SCVMM 2012 via powershell

This quick post will provide an example of how to create a Virtual Machine (VM) based off an VMM template that utilizes differencing disks. 

This is special because VMM does not support this natively.  So you have to contact the target HyperV host (via WMI) to create the Diff disk.  In addition to need to make sure that the HyperV host has the parent VHD already in place. 

The Powershell cmdlet below does the following
  1. Looks up the specified Hardware profile
  2. Looks up the specified template (this is used to get the parent VHD location/name)
  3. Looks up info on the specified target HyperV host (so we can find the placement drive)
  4. Checks to see if the ParentVHD already exists on the HyperV hosts Placement Drive
  5. If the VHD does not exist it copies it to the HyperV host
  6. Creates Diff Disk via WMI on hyperV host pointing to parent VHD
  7. Creates the VM via the New-SCVirtualMachine cmdlet using the UseLocalVirtualHardDisk command. (this tells VMM to allow Diff disks).
It can be downloaded from http://dl.dropbox.com/u/3275573/Create_Diff_VM_From_Template.ps1
    param($VMName,$TemplateName = "Windows Server 2008 R2 SP1 Enterprise", $HardwareProfileName = "ServerHardware", $VMMHost = "SCVMM",$targethostname = $null)
    
    $Err = 0
    
    If ($VMName -eq $null)
    {
      Write-Host "`nERROR: Incorrect arguments" -foregroundcolor red -backgroundcolor black
       Write-Host "`nREQUIRED ARGUMENTS:" -foregroundcolor cyan
       Write-Host "`n   -VMName `"Name of the VM to create`"" -foregroundcolor cyan
       Write-Host "`n   -TemplateName `"Name of the VMM Template`"" -foregroundcolor cyan
       Write-Host "`n   -HardwareProfileName `"Name of the VMM Hardware Profile to use with the template`"" -foregroundcolor cyan
       Write-Host "`n   -VMMHost `"VMM Computername`"" -foregroundcolor cyan
       Write-Host "`n   -targetHostname `"Computername of HyperV host to target`"" -foregroundcolor cyan
      Exit $Err
    }
    
    function CreateDiffDiskOnHost
    {
                    param([string]$hostComputerName, [string]$childPath, [string]$parentPath)
                    #get the image mgmt service instance for the host computer
                    $VHDService = get-wmiobject -class "Msvm_ImageManagementService" -namespace "root\virtualization" -computername $hostComputerName
                    
                    #create a differencing disk from the base disk
                    $Result = $VHDService.CreateDifferencingVirtualHardDisk($childPath, $parentPath)
    }
    function TestFileLock {
        ## Attempts to open a file and trap the resulting error if the file is already open/locked
        param ([string]$filePath )
        $filelocked = $false
        $fileInfo = New-Object System.IO.FileInfo $filePath
        trap {
            Set-Variable -name locked -value $true -scope 1
            continue
        }
        $fileStream = $fileInfo.Open( [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None )
        if ($fileStream) {
            $fileStream.Close()
        }
        $obj = New-Object Object
        $obj | Add-Member Noteproperty FilePath -value $filePath
        $obj | Add-Member Noteproperty IsLocked -value $filelocked
        $obj
    }
    
    
    write-host "VMName is $VMName"
    write-host "Template is $TemplateName"
    write-host "Hardware Profile is $HardwareProfileName"
    write-host "VMMHost is $VMMHost"
    write-host "Target Host is $targethostname"
    
    $guid = [guid]::NewGuid()
    
    write-host "Lookup the base hardware Profile $HardwareProfileName"
    $HardwareProfile = Get-SCHardwareProfile -VMMServer $VMMHost  | where {$_.Name -eq $HardwareProfileName}
    if ($HardwareProfile -eq $null)
        {
            write-host "Failed to lookup HardwareProfile $HardwareProfileName"  -foregroundcolor red -backgroundcolor black
         EXIT 1
        }
    
    write-host "Getting information for template $TemplateName"
    $Template = Get-SCVMTemplate -VMMServer $VMMHost  -All | where {$_.Name -eq $TemplateName}
     if ($Template -eq $null)
        {
            write-host "Failed to lookup Template $TemplateName"  -foregroundcolor red -backgroundcolor black
         EXIT 1
        }
        
    #Get the VHD info for the template
    $VHD =  Get-SCVirtualharddisk | where {$_.Name -eq $template.VirtualDiskDrives[0].VirtualHardDisk}
    
    write-host "Template VHD Path " $VHD.SharePath
    
    if ($targethostname -eq $null)
    {
        write-host "Invalid targethostname"  -foregroundcolor red -backgroundcolor black
        exit 1
    }
    $vmhost = Get-SCVMHost $targethostname
    
    $vmHostPath = [string]$vmhost.vmpaths
    write-host "Target VMHost: "  $vmhost.name
    write-host "Target Drive: "  $vmhost.VMPaths
    
    $remotePath = "\\" + $vmhost.name + "\" + $vmHostPath.substring(0,1) + "$\" + [system.io.path]::GetFileName($VHD.SharePath)
    "Checking to see if Parent VHD exists on HV Host Drive"
    "RemotePath: $remotePath"
    
    if (Test-Path $remotePath)
    {
     "Parent VHD already exists on HV Host"
    }
    else
    {
     "$RemotePath does not exist, going to Copy"
     [System.IO.File]::Copy($VHD.SharePath,$remotePath); 
    }
    
    "Creating Diff Disk"
    $targetVHDPath = $vmHostPath + $VMName + ".vhd"
    $ParentVHDPath = $vmHostPath + [system.io.path]::GetFileName($VHD.SharePath)
    CreateDiffDiskOnHost "$vmhost" "$targetVHDPath" "$ParentVHDPath"
    Start-Sleep -s 20
    
    $targetVHDRemotePath = "\\" + $vmhost.name + "\" + $vmHostPath.substring(0,1) + "$\" + $VMName + ".vhd"
    if (Test-Path $targetVHDRemotePath)
    {
     "Diff Disk Created at:$targetVHDRemotePath"
    }
    else
    {
     "$targetVHDRemotePath does not exist yet.  Sleeping for a few"
     Start-Sleep -s 30
        if (Test-Path $targetVHDRemotePath)
        {
            "Disk was created."
        }
        else
        {
            write-host "Failed to find VHD $targetVHDRemotePath after sleep, exiting" -foregroundcolor red -backgroundcolor black
            exit 1
        }
    
    }
    #Set a random startup delay to reduce VM startup IOPs overload
    $startDelay = Get-Random -minimum 1 -maximum 30
    
    
    $lockstate = TestFileLock "$targetVHDRemotePath"
    if ($lockstate.IsLocked)
    {
        "File locked, sleeping"
        Start-Sleep -s 30
    }
    
    $mv = move-SCvirtualharddisk -Bus 0 -Lun 0 -IDE -path $targetVHDPath  -jobgroup $guid
    $description = $template.tag
    New-SCVirtualMachine -Name $vmName -VMHost $vmHost -VMTemplate $template -UseLocalVirtualHardDisk -HardwareProfile $HardwareProfile -ComputerName $vmName -path $vmHostPath -delaystartseconds $startDelay  -Description "$description" -mergeanswerfile $true -BlockDynamicOptimization $false -StartVM -JobGroup "$guid" -RunAsynchronously -StartAction "AlwaysAutoTurnOnVM" -StopAction "SaveVM"
    

    Sunday, July 17, 2011

    Managing Microsoft IIS, Active Directory and DNS from .net

    Update 7/17/2011:  New links

    This code was one of my first coding project from 11-10-2006

    Today I am posting sample code on how to manage IIS 6 and Active directory using ADSI in VB.NET.
    And managing DNS (creating zones, records and enumeration) using WMI in VB.NET.
    There are four separate projects. 
    This code is posted as-is!  It is to be used as a sample on how to do the work.  It is not intended to be used in production!
    http://dl.dropbox.com/u/3275573/blog/web.zip - ADSI management of IIS 6 Sites and AppPools
    http://dl.dropbox.com/u/3275573/blog/DNS.zip - WMI management of Microsoft DNS Zones and Records
    http://dl.dropbox.com/u/3275573/blog/ActiveDirectory.zip- ADSI management of Active Directory contacts, Groups, Users, Recipient Policies, Accepted Domains objects (Exchange 2007)
    http://dl.dropbox.com/u/3275573/blog/IISSiteID.zip - C# code on generating IIS SiteID

    Saturday, June 18, 2011

    Disk Quota and .net (WMI and Microsoft.DiskQuota.1)

    Repost from old Blog

    Today I had a con-call to talk about disk quota and how to automate the setting and reading of Quota. So i thought that I would post a little about Disk quota stuff.

    There are 2 okay options.

    #1 WMI (way to slow for a lot of things (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/disk_quota_provider.asp))

    #2 Microsoft.DiskQuota.1

    So my team needed a way to enumerate a users current quota limits and then + or - from them. WMI was very slow to do this. But DiskQuota.1 is quite fast. It is not well documented that it works on remote servers either. So I wrote a little something up.

    So here is some cs (and vb.net) that has functions on how to get and set quota info with Microsoft.diskquota.1

    CSharp: http://dl.dropbox.com/u/3275573/blog/QuotaFunctions.cs.txt
    VB.NET: http://dl.dropbox.com/u/3275573/blog/QuotaFunctions.vb.txt

    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.

    How does IIS generate the Site ID?

    Repost from old blog

    So in IIS 6 (and maybe IIS 7) when you create a new site programmatically you have the option to specify a SiteID or you can let IIS 6 do it for you. 

    If you let it do it for you it will make this kinda hash of the site name.  You have to use this ID when you are doing any modifications to the site (programmatically).  So it would be the value in IIS://<servername>/W3SVC/<SiteID>

    So how do you get the SiteID?

    • Well you could create the site then enumerate it from WMI or ADSI. 
    • Use my little c# function below to generate the sitename

     



    public static uint GenerateSiteID(string SiteName)
    {
    uint id = 0;
    char[] arr = SiteName.ToCharArray(); //Convert the sitename to a Char Array
    for (int i = 0; i < arr.Length; i++)
    {
    char c = arr[i];
    int intc = c;

    int upper = intc & '\x00df'; //Upper case the letter
    id = (
    uint)(id * 101) + (uint)upper;
    }
    return (id % Int32.MaxValue) + 1; //do a MOD and add 1
    }

    Now a good thing to remember is that this might not be the sitename the IIS is using.  If there is a SiteID collision then IIS will try to move the ID up by 1 digit then try again.  So dont let this be the end all be all of how this is determined. 

    Using the code above is much faster then parsing through all the sites via ADSI or WMI to get the siteID.  So if you have 2000 sites on a server the site was created most recently (bottom of the Metabase) will take longer to query for then the first site created (top of the metabase). 

    Also note that if you try to convert this code to VB.net you will get an exception becasue VB.net does more bounds checking.

    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

    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 ...