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