def get_vlan_list(row): concatenated_bits = b'' for column in ('vlanTrunkPortVlansEnabled', 'vlanTrunkPortVlansEnabled2k', 'vlanTrunkPortVlansEnabled3k', 'vlanTrunkPortVlansEnabled4k'): value = row[column] or b'' concatenated_bits += value.ljust(CHARS_IN_1024_BITS, b'\x00') enabled = BitVector(concatenated_bits) return as_bitvector and enabled or enabled.get_set_bits()
def _compute_octet_string(hexstring, port, action='enable'): """ hexstring: the returnvalue of the snmpquery port: the number of the port to add """ bit = BitVector(hexstring) # Add port to string port -= 1 if action == 'enable': bit[port] = 1 else: bit[port] = 0 return bit.to_bytes()
def test_chunkify(self): vlans = [10, 33, 513, 1023, 1025, 2048, 4095] b = BitVector(512 * '\000') for vlan in vlans: b[vlan] = 1 self.assertEqual(b.get_set_bits(), vlans) first, second, third, fourth = SNMPHandler._chunkify(b, 4) self.assertEqual(first.get_set_bits(), [10, 33, 513, 1023]) self.assertEqual(second.get_set_bits(), [1]) self.assertEqual(third.get_set_bits(), [0]) self.assertEqual(fourth.get_set_bits(), [1023])
def get_vlan_list(row): concatenated_bits = '' # There is no point in concatening more bitstrings if one of them # are empty, that would just produced a skewed result. for column in ('vlanTrunkPortVlansEnabled', 'vlanTrunkPortVlansEnabled2k', 'vlanTrunkPortVlansEnabled3k', 'vlanTrunkPortVlansEnabled4k'): if row[column]: concatenated_bits += row[column] else: break enabled = BitVector(concatenated_bits) return as_bitvector and enabled or enabled.get_set_bits()
def get_native_and_trunked_vlans(self, interface): ifindex = interface.ifindex native_vlan = self._query_netbox(self.TRUNKPORTNATIVEVLAN, ifindex) blocks = [ self._query_netbox(oid, ifindex) or '' for oid in (self.TRUNKPORTVLANSENABLED, self.TRUNKPORTVLANSENABLED2K, self.TRUNKPORTVLANSENABLED3K, self.TRUNKPORTVLANSENABLED4K)] bitstring = "".join(value.ljust(CHARS_IN_1024_BITS, '\x00') for value in blocks) bitvector = BitVector(bitstring) return native_vlan, bitvector.get_set_bits()
def vlan_list_to_hex(vlans): """Convert a list of VLAN numbers to a hexadecimal string. The hexadecimal string is suitable for insertion into the swportallowedvlan table. """ # Make sure there are at least 256 digits (128 octets) in the # resulting hex string. This is necessary for parts of NAV to # parse the hexstring correctly. max_vlan = sorted(vlans)[-1] needed_octets = int(math.ceil((max_vlan + 1) / 8.0)) bits = BitVector('\x00' * max(needed_octets, 128)) for vlan in vlans: bits[vlan] = True return bits.to_hex()
def vlan_list_to_hex(vlans): """Convert a list of VLAN numbers to a hexadecimal string. The hexadecimal string is suitable for insertion into the swportallowedvlan table. """ # Make sure there are at least 256 digits (128 octets) in the # resulting hex string. This is necessary for parts of NAV to # parse the hexstring correctly. max_vlan = sorted(vlans)[-1] needed_octets = int(math.ceil((max_vlan+1) / 8.0)) bits = BitVector('\x00' * max(needed_octets, 128)) for vlan in vlans: bits[vlan] = True return bits.to_hex()
def set_trunk_vlans(self, interface, vlans): """Set trunk vlans Initialize a BitVector with all 4096 vlans set to 0. Then fill in all vlans. As Cisco has 4 different oids to set all vlans on the trunk, we divide this bitvector into one bitvector for each oid, and set each of those. """ ifindex = interface.ifindex bitvector = BitVector(512 * b'\x00') # initialize all-zero bitstring for vlan in vlans: bitvector[int(vlan)] = 1 chunks = self._chunkify(bitvector, 4) for oid in [ self.TRUNKPORTVLANSENABLED, self.TRUNKPORTVLANSENABLED2K, self.TRUNKPORTVLANSENABLED3K, self.TRUNKPORTVLANSENABLED4K ]: bitvector_chunk = next(chunks) try: self._set_netbox_value(oid, ifindex, 's', bitvector_chunk.to_bytes()) except SnmpError as error: _logger.error('Error setting trunk vlans on %s ifindex %s: %s', self.netbox, ifindex, error) break
def get_native_and_trunked_vlans(self, interface): """Get the trunked vlans on this interface For each available vlan, fetch list of interfaces that forward this vlan. If the interface index is in this list, add the vlan to the return list. :returns native vlan + list of trunked vlan """ native_vlan = self.get_native_vlan(interface) bitvector_index = interface.baseport - 1 vlans = [] for vlan in self.get_available_vlans(): if vlan == native_vlan: continue octet_string = self._query_netbox(self.CURRENT_VLAN_EGRESS_PORTS, vlan) or b'' bitvector = BitVector(octet_string) try: if bitvector[bitvector_index]: vlans.append(vlan) except IndexError: _logger.error('Baseport index was out of bounds ' 'for StaticEgressPorts') return native_vlan, vlans
def _chunkify(bitvector, chunks): """Divide bitvector into chunks number of chunks :returns a new bitvector instance with the chunk """ hexes = bitvector.to_hex() chunksize = len(bitvector.to_hex()) // chunks for i in range(0, len(hexes), chunksize): yield BitVector.from_hex(hexes[i:i + chunksize])
def get_native_and_trunked_vlans(self, interface): native_vlan = self.get_interface_native_vlan(interface) bitvector_index = interface.baseport - 1 vlans = [] for vlan in self.get_netbox_vlan_tags(): if vlan == native_vlan: continue octet_string = (self._query_netbox(self.CURRENT_VLAN_EGRESS_PORTS, vlan) or b'') bitvector = BitVector(octet_string) try: if bitvector[bitvector_index]: vlans.append(vlan) except IndexError: _logger.error('Baseport index was out of bounds ' 'for StaticEgressPorts') return native_vlan, vlans
def get_native_and_trunked_vlans(self, interface): """Get the trunked vlans on this interface For each available vlan, fetch list of interfaces that forward this vlan. If the interface index is in this list, add the vlan to the return list. :returns native vlan + list of trunked vlan """ native_vlan = self.get_vlan(interface.baseport) bitvector_index = interface.baseport - 1 vlans = [] for vlan in self.get_available_vlans(): if vlan == native_vlan: continue octet_string = self._query_netbox(self.VLAN_EGRESS_PORTS, vlan) bitvector = BitVector(octet_string) if bitvector[bitvector_index]: vlans.append(vlan) return native_vlan, vlans
def _get_egress_interfaces_as_bitvector(self, vlan): octet_string = self._query_netbox(self.CURRENT_VLAN_EGRESS_PORTS, vlan) return BitVector(octet_string)