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